From 4456904aebe55b2984ea9b218d61471a128d5475 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 9 Mar 2022 15:46:56 -0600 Subject: [PATCH] Final Solution --- .../HLlib.dir/src/HiddenLines.cpp.o | Bin 29000 -> 53728 bytes .../HLlib.dir/src/HiddenLines.cpp.o.d | 548 ++++ .../linelib.dir/compiler_depend.internal | 13 - .../linelib.dir/compiler_depend.make | 43 +- build/CMakeFiles/linelib.dir/src/Line.cpp.o.d | 11 +- build/libHLlib.a | Bin 30288 -> 57420 bytes build/main | Bin 39160 -> 55648 bytes src/HiddenLines.cpp | 39 +- src/Line.cpp | 6 +- src/gnuplot-iostream.h | 2586 +++++++++++++++++ 10 files changed, 3162 insertions(+), 84 deletions(-) create mode 100644 src/gnuplot-iostream.h diff --git a/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o b/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o index 928d673e32b3756b30695e1e022a073fe31dae2f..de6a8e7ee3919cb65204230cf8bab5a9b3059b0d 100644 GIT binary patch literal 53728 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 delta 9883 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 JXF{3g@_zsf((3>K diff --git a/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o.d b/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o.d index 510c284..3058386 100644 --- a/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o.d +++ b/build/CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o.d @@ -185,6 +185,554 @@ CMakeFiles/HLlib.dir/src/HiddenLines.cpp.o: \ /usr/include/c++/11.2.0/bits/stl_bvector.h \ /usr/include/c++/11.2.0/bits/vector.tcc \ /usr/include/c++/11.2.0/pstl/execution_defs.h \ + /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/gnuplot-iostream.h \ + /usr/include/c++/11.2.0/sstream /usr/include/c++/11.2.0/bits/sstream.tcc \ + /usr/include/c++/11.2.0/iomanip /usr/include/c++/11.2.0/locale \ + /usr/include/c++/11.2.0/bits/locale_facets_nonio.h \ + /usr/include/c++/11.2.0/ctime \ + /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/time_members.h \ + /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/messages_members.h \ + /usr/include/libintl.h \ + /usr/include/c++/11.2.0/bits/locale_facets_nonio.tcc \ + /usr/include/c++/11.2.0/bits/locale_conv.h \ + /usr/include/c++/11.2.0/bits/unique_ptr.h \ + /usr/include/c++/11.2.0/bits/quoted_string.h \ + /usr/include/c++/11.2.0/complex \ + /usr/include/boost/iostreams/device/file_descriptor.hpp \ + /usr/include/boost/cstdint.hpp /usr/include/boost/config.hpp \ + /usr/include/boost/config/user.hpp \ + /usr/include/boost/config/detail/select_compiler_config.hpp \ + /usr/include/boost/config/compiler/gcc.hpp \ + /usr/include/c++/11.2.0/cstddef \ + /usr/include/boost/config/detail/select_stdlib_config.hpp \ + /usr/include/c++/11.2.0/version \ + /usr/include/boost/config/stdlib/libstdcpp3.hpp /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \ + /usr/include/bits/confname.h /usr/include/bits/getopt_posix.h \ + /usr/include/bits/getopt_core.h /usr/include/bits/unistd_ext.h \ + /usr/include/linux/close_range.h \ + /usr/include/boost/config/detail/select_platform_config.hpp \ + /usr/include/boost/config/platform/linux.hpp \ + /usr/include/boost/config/detail/posix_features.hpp \ + /usr/include/boost/config/detail/suffix.hpp \ + /usr/include/boost/config/helper_macros.hpp \ + /usr/include/boost/config/detail/cxx_composite.hpp \ + /usr/include/boost/iostreams/categories.hpp \ + /usr/include/boost/iostreams/detail/config/auto_link.hpp \ + /usr/include/boost/config/auto_link.hpp \ + /usr/include/boost/iostreams/detail/config/dyn_link.hpp \ + /usr/include/boost/detail/workaround.hpp \ + /usr/include/boost/config/workaround.hpp \ + /usr/include/boost/iostreams/detail/config/windows_posix.hpp \ + /usr/include/boost/iostreams/detail/file_handle.hpp \ + /usr/include/boost/iostreams/detail/ios.hpp \ + /usr/include/boost/iostreams/detail/config/wide_streams.hpp \ + /usr/include/boost/iostreams/detail/path.hpp \ + /usr/include/c++/11.2.0/cstring /usr/include/string.h \ + /usr/include/strings.h /usr/include/boost/static_assert.hpp \ + /usr/include/boost/type.hpp /usr/include/boost/type_traits/is_same.hpp \ + /usr/include/boost/type_traits/integral_constant.hpp \ + /usr/include/boost/iostreams/positioning.hpp \ + /usr/include/boost/integer_traits.hpp /usr/include/boost/limits.hpp \ + /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include-fixed/limits.h \ + /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include-fixed/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ + /usr/include/bits/uio_lim.h \ + /usr/include/boost/iostreams/detail/config/codecvt.hpp \ + /usr/include/boost/iostreams/detail/config/fpos.hpp \ + /usr/include/boost/iostreams/detail/config/disable_warnings.hpp \ + /usr/include/boost/iostreams/detail/config/enable_warnings.hpp \ + /usr/include/boost/shared_ptr.hpp \ + /usr/include/boost/smart_ptr/shared_ptr.hpp \ + /usr/include/boost/smart_ptr/detail/shared_count.hpp \ + /usr/include/boost/smart_ptr/bad_weak_ptr.hpp \ + /usr/include/boost/smart_ptr/detail/sp_counted_base.hpp \ + /usr/include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp \ + /usr/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp \ + /usr/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp \ + /usr/include/boost/smart_ptr/detail/sp_typeinfo_.hpp \ + /usr/include/boost/smart_ptr/detail/sp_counted_impl.hpp \ + /usr/include/boost/smart_ptr/detail/sp_noexcept.hpp \ + /usr/include/boost/checked_delete.hpp \ + /usr/include/boost/core/checked_delete.hpp \ + /usr/include/boost/core/addressof.hpp /usr/include/c++/11.2.0/memory \ + /usr/include/c++/11.2.0/bits/stl_raw_storage_iter.h \ + /usr/include/c++/11.2.0/bits/align.h /usr/include/c++/11.2.0/bit \ + /usr/include/c++/11.2.0/bits/shared_ptr.h \ + /usr/include/c++/11.2.0/bits/shared_ptr_base.h \ + /usr/include/c++/11.2.0/bits/allocated_ptr.h \ + /usr/include/c++/11.2.0/ext/concurrence.h \ + /usr/include/c++/11.2.0/bits/shared_ptr_atomic.h \ + /usr/include/c++/11.2.0/bits/atomic_base.h \ + /usr/include/c++/11.2.0/bits/atomic_lockfree_defines.h \ + /usr/include/c++/11.2.0/backward/auto_ptr.h \ + /usr/include/c++/11.2.0/pstl/glue_memory_defs.h \ + /usr/include/boost/smart_ptr/detail/sp_disable_deprecated.hpp \ + /usr/include/boost/throw_exception.hpp \ + /usr/include/boost/exception/exception.hpp \ + /usr/include/boost/assert/source_location.hpp \ + /usr/include/boost/current_function.hpp \ + /usr/include/boost/smart_ptr/detail/sp_convertible.hpp \ + /usr/include/boost/smart_ptr/detail/sp_nullptr_t.hpp \ + /usr/include/boost/assert.hpp /usr/include/assert.h \ + /usr/include/boost/smart_ptr/detail/spinlock_pool.hpp \ + /usr/include/boost/smart_ptr/detail/spinlock.hpp \ + /usr/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp \ + /usr/include/boost/smart_ptr/detail/yield_k.hpp \ + /usr/include/boost/smart_ptr/detail/sp_thread_pause.hpp \ + /usr/include/boost/smart_ptr/detail/sp_thread_sleep.hpp \ + /usr/include/boost/config/pragma_message.hpp \ + /usr/include/boost/smart_ptr/detail/operator_bool.hpp \ + /usr/include/boost/smart_ptr/detail/local_sp_deleter.hpp \ + /usr/include/boost/smart_ptr/detail/local_counted_base.hpp \ + /usr/include/boost/config/abi_prefix.hpp \ + /usr/include/boost/config/abi_suffix.hpp \ + /usr/include/boost/iostreams/stream.hpp \ + /usr/include/boost/iostreams/constants.hpp \ + /usr/include/boost/iostreams/detail/char_traits.hpp \ + /usr/include/boost/iostreams/detail/config/overload_resolution.hpp \ + /usr/include/boost/iostreams/detail/config/gcc.hpp \ + /usr/include/boost/iostreams/detail/forward.hpp \ + /usr/include/boost/iostreams/detail/config/limits.hpp \ + /usr/include/boost/iostreams/detail/push_params.hpp \ + /usr/include/boost/preprocessor/arithmetic/dec.hpp \ + /usr/include/boost/preprocessor/config/config.hpp \ + /usr/include/boost/preprocessor/config/limits.hpp \ + /usr/include/boost/preprocessor/arithmetic/limits/dec_256.hpp \ + /usr/include/boost/preprocessor/arithmetic/inc.hpp \ + /usr/include/boost/preprocessor/arithmetic/limits/inc_256.hpp \ + /usr/include/boost/preprocessor/punctuation/comma_if.hpp \ + /usr/include/boost/preprocessor/control/if.hpp \ + /usr/include/boost/preprocessor/control/iif.hpp \ + /usr/include/boost/preprocessor/logical/bool.hpp \ + /usr/include/boost/preprocessor/logical/limits/bool_256.hpp \ + /usr/include/boost/preprocessor/facilities/empty.hpp \ + /usr/include/boost/preprocessor/punctuation/comma.hpp \ + /usr/include/boost/preprocessor/repetition/enum_binary_params.hpp \ + /usr/include/boost/preprocessor/cat.hpp \ + /usr/include/boost/preprocessor/repetition/repeat.hpp \ + /usr/include/boost/preprocessor/debug/error.hpp \ + /usr/include/boost/preprocessor/detail/auto_rec.hpp \ + /usr/include/boost/preprocessor/detail/limits/auto_rec_256.hpp \ + /usr/include/boost/preprocessor/tuple/eat.hpp \ + /usr/include/boost/preprocessor/repetition/limits/repeat_256.hpp \ + /usr/include/boost/preprocessor/tuple/elem.hpp \ + /usr/include/boost/preprocessor/facilities/expand.hpp \ + /usr/include/boost/preprocessor/facilities/overload.hpp \ + /usr/include/boost/preprocessor/variadic/size.hpp \ + /usr/include/boost/preprocessor/facilities/check_empty.hpp \ + /usr/include/boost/preprocessor/variadic/has_opt.hpp \ + /usr/include/boost/preprocessor/variadic/limits/size_64.hpp \ + /usr/include/boost/preprocessor/tuple/rem.hpp \ + /usr/include/boost/preprocessor/tuple/detail/is_single_return.hpp \ + /usr/include/boost/preprocessor/variadic/elem.hpp \ + /usr/include/boost/preprocessor/variadic/limits/elem_64.hpp \ + /usr/include/boost/preprocessor/repetition/enum_params.hpp \ + /usr/include/boost/preprocessor/repetition/repeat_from_to.hpp \ + /usr/include/boost/preprocessor/arithmetic/add.hpp \ + /usr/include/boost/preprocessor/control/while.hpp \ + /usr/include/boost/preprocessor/list/fold_left.hpp \ + /usr/include/boost/preprocessor/list/detail/fold_left.hpp \ + /usr/include/boost/preprocessor/control/expr_iif.hpp \ + /usr/include/boost/preprocessor/list/adt.hpp \ + /usr/include/boost/preprocessor/detail/is_binary.hpp \ + /usr/include/boost/preprocessor/detail/check.hpp \ + /usr/include/boost/preprocessor/logical/compl.hpp \ + /usr/include/boost/preprocessor/list/detail/limits/fold_left_256.hpp \ + /usr/include/boost/preprocessor/list/limits/fold_left_256.hpp \ + /usr/include/boost/preprocessor/list/fold_right.hpp \ + /usr/include/boost/preprocessor/list/detail/fold_right.hpp \ + /usr/include/boost/preprocessor/list/reverse.hpp \ + /usr/include/boost/preprocessor/facilities/identity.hpp \ + /usr/include/boost/preprocessor/list/detail/limits/fold_right_256.hpp \ + /usr/include/boost/preprocessor/logical/bitand.hpp \ + /usr/include/boost/preprocessor/control/detail/while.hpp \ + /usr/include/boost/preprocessor/control/detail/limits/while_256.hpp \ + /usr/include/boost/preprocessor/control/limits/while_256.hpp \ + /usr/include/boost/preprocessor/logical/bitor.hpp \ + /usr/include/boost/preprocessor/arithmetic/detail/is_maximum_number.hpp \ + /usr/include/boost/preprocessor/comparison/equal.hpp \ + /usr/include/boost/preprocessor/comparison/not_equal.hpp \ + /usr/include/boost/preprocessor/comparison/limits/not_equal_256.hpp \ + /usr/include/boost/preprocessor/arithmetic/detail/maximum_number.hpp \ + /usr/include/boost/preprocessor/arithmetic/detail/is_minimum_number.hpp \ + /usr/include/boost/preprocessor/logical/not.hpp \ + /usr/include/boost/preprocessor/arithmetic/sub.hpp \ + /usr/include/boost/preprocessor/logical/and.hpp \ + /usr/include/boost/iostreams/detail/iostream.hpp \ + /usr/include/boost/iostreams/detail/select.hpp \ + /usr/include/boost/type_traits/is_base_and_derived.hpp \ + /usr/include/boost/type_traits/intrinsics.hpp \ + /usr/include/boost/type_traits/detail/config.hpp \ + /usr/include/boost/version.hpp \ + /usr/include/boost/type_traits/remove_cv.hpp \ + /usr/include/boost/mpl/eval_if.hpp /usr/include/boost/mpl/if.hpp \ + /usr/include/boost/mpl/aux_/value_wknd.hpp \ + /usr/include/boost/mpl/aux_/static_cast.hpp \ + /usr/include/boost/mpl/aux_/config/workaround.hpp \ + /usr/include/boost/mpl/aux_/config/integral.hpp \ + /usr/include/boost/mpl/aux_/config/msvc.hpp \ + /usr/include/boost/mpl/aux_/config/eti.hpp \ + /usr/include/boost/mpl/aux_/na_spec.hpp \ + /usr/include/boost/mpl/lambda_fwd.hpp \ + /usr/include/boost/mpl/void_fwd.hpp \ + /usr/include/boost/mpl/aux_/adl_barrier.hpp \ + /usr/include/boost/mpl/aux_/config/adl.hpp \ + /usr/include/boost/mpl/aux_/config/intel.hpp \ + /usr/include/boost/mpl/aux_/config/gcc.hpp \ + /usr/include/boost/mpl/aux_/na.hpp /usr/include/boost/mpl/bool.hpp \ + /usr/include/boost/mpl/bool_fwd.hpp \ + /usr/include/boost/mpl/integral_c_tag.hpp \ + /usr/include/boost/mpl/aux_/config/static_constant.hpp \ + /usr/include/boost/mpl/aux_/na_fwd.hpp \ + /usr/include/boost/mpl/aux_/config/ctps.hpp \ + /usr/include/boost/mpl/aux_/config/lambda.hpp \ + /usr/include/boost/mpl/aux_/config/ttp.hpp \ + /usr/include/boost/mpl/int.hpp /usr/include/boost/mpl/int_fwd.hpp \ + /usr/include/boost/mpl/aux_/nttp_decl.hpp \ + /usr/include/boost/mpl/aux_/config/nttp.hpp \ + /usr/include/boost/mpl/aux_/integral_wrapper.hpp \ + /usr/include/boost/mpl/aux_/lambda_arity_param.hpp \ + /usr/include/boost/mpl/aux_/template_arity_fwd.hpp \ + /usr/include/boost/mpl/aux_/arity.hpp \ + /usr/include/boost/mpl/aux_/config/dtp.hpp \ + /usr/include/boost/mpl/aux_/preprocessor/params.hpp \ + /usr/include/boost/mpl/aux_/config/preprocessor.hpp \ + /usr/include/boost/preprocessor/comma_if.hpp \ + /usr/include/boost/preprocessor/repeat.hpp \ + /usr/include/boost/preprocessor/inc.hpp \ + /usr/include/boost/mpl/aux_/preprocessor/enum.hpp \ + /usr/include/boost/mpl/aux_/preprocessor/def_params_tail.hpp \ + /usr/include/boost/mpl/limits/arity.hpp \ + /usr/include/boost/preprocessor/identity.hpp \ + /usr/include/boost/preprocessor/empty.hpp \ + /usr/include/boost/mpl/aux_/config/overload_resolution.hpp \ + /usr/include/boost/mpl/aux_/lambda_support.hpp \ + /usr/include/boost/mpl/identity.hpp /usr/include/boost/mpl/void.hpp \ + /usr/include/boost/iostreams/stream_buffer.hpp \ + /usr/include/boost/iostreams/detail/streambuf/direct_streambuf.hpp \ + /usr/include/boost/core/typeinfo.hpp \ + /usr/include/boost/core/demangle.hpp /usr/include/c++/11.2.0/cxxabi.h \ + /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/cxxabi_tweaks.h \ + /usr/include/boost/iostreams/detail/error.hpp \ + /usr/include/boost/iostreams/detail/execute.hpp \ + /usr/include/boost/preprocessor/iteration/local.hpp \ + /usr/include/boost/preprocessor/slot/slot.hpp \ + /usr/include/boost/preprocessor/slot/detail/def.hpp \ + /usr/include/boost/utility/result_of.hpp \ + /usr/include/boost/type_traits/is_class.hpp \ + /usr/include/boost/type_traits/is_pointer.hpp \ + /usr/include/boost/type_traits/is_member_function_pointer.hpp \ + /usr/include/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp \ + /usr/include/boost/type_traits/remove_reference.hpp \ + /usr/include/boost/type_traits/declval.hpp \ + /usr/include/boost/type_traits/add_rvalue_reference.hpp \ + /usr/include/boost/type_traits/is_void.hpp \ + /usr/include/boost/type_traits/is_reference.hpp \ + /usr/include/boost/type_traits/is_lvalue_reference.hpp \ + /usr/include/boost/type_traits/is_rvalue_reference.hpp \ + /usr/include/boost/type_traits/conditional.hpp \ + /usr/include/boost/type_traits/type_identity.hpp \ + /usr/include/boost/core/enable_if.hpp \ + /usr/include/boost/utility/detail/result_of_variadic.hpp \ + /usr/include/boost/preprocessor/iteration/detail/local.hpp \ + /usr/include/boost/preprocessor/iteration/detail/limits/local_256.hpp \ + /usr/include/boost/iostreams/detail/functional.hpp \ + /usr/include/boost/iostreams/close.hpp \ + /usr/include/boost/iostreams/flush.hpp \ + /usr/include/boost/iostreams/detail/dispatch.hpp \ + /usr/include/boost/iostreams/traits.hpp \ + /usr/include/boost/iostreams/detail/bool_trait_def.hpp \ + /usr/include/boost/iostreams/detail/template_params.hpp \ + /usr/include/boost/preprocessor/control/expr_if.hpp \ + /usr/include/boost/type_traits/detail/yes_no_type.hpp \ + /usr/include/boost/iostreams/detail/is_iterator_range.hpp \ + /usr/include/boost/iostreams/detail/select_by_size.hpp \ + /usr/include/boost/iostreams/detail/wrap_unwrap.hpp \ + /usr/include/boost/iostreams/detail/enable_if_stream.hpp \ + /usr/include/boost/utility/enable_if.hpp \ + /usr/include/boost/iostreams/traits_fwd.hpp /usr/include/boost/ref.hpp \ + /usr/include/boost/core/ref.hpp /usr/include/boost/mpl/or.hpp \ + /usr/include/boost/mpl/aux_/config/use_preprocessed.hpp \ + /usr/include/boost/mpl/aux_/nested_type_wknd.hpp \ + /usr/include/boost/mpl/aux_/include_preprocessed.hpp \ + /usr/include/boost/mpl/aux_/config/compiler.hpp \ + /usr/include/boost/preprocessor/stringize.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/or.hpp \ + /usr/include/boost/range/iterator_range.hpp \ + /usr/include/boost/range/iterator_range_core.hpp \ + /usr/include/boost/iterator/iterator_traits.hpp \ + /usr/include/c++/11.2.0/iterator \ + /usr/include/c++/11.2.0/bits/stream_iterator.h \ + /usr/include/boost/iterator/iterator_facade.hpp \ + /usr/include/boost/iterator/interoperable.hpp \ + /usr/include/boost/type_traits/is_convertible.hpp \ + /usr/include/boost/type_traits/is_complete.hpp \ + /usr/include/boost/type_traits/is_function.hpp \ + /usr/include/boost/type_traits/detail/is_function_cxx_11.hpp \ + /usr/include/boost/type_traits/is_array.hpp \ + /usr/include/boost/type_traits/is_arithmetic.hpp \ + /usr/include/boost/type_traits/is_integral.hpp \ + /usr/include/boost/type_traits/is_floating_point.hpp \ + /usr/include/boost/type_traits/is_abstract.hpp \ + /usr/include/boost/type_traits/add_lvalue_reference.hpp \ + /usr/include/boost/type_traits/add_reference.hpp \ + /usr/include/boost/iterator/detail/config_def.hpp \ + /usr/include/boost/iterator/detail/config_undef.hpp \ + /usr/include/boost/iterator/iterator_categories.hpp \ + /usr/include/boost/mpl/placeholders.hpp /usr/include/boost/mpl/arg.hpp \ + /usr/include/boost/mpl/arg_fwd.hpp \ + /usr/include/boost/mpl/aux_/na_assert.hpp \ + /usr/include/boost/mpl/assert.hpp /usr/include/boost/mpl/not.hpp \ + /usr/include/boost/mpl/aux_/yes_no.hpp \ + /usr/include/boost/mpl/aux_/config/arrays.hpp \ + /usr/include/boost/mpl/aux_/config/gpu.hpp \ + /usr/include/boost/mpl/aux_/config/pp_counter.hpp \ + /usr/include/boost/mpl/aux_/arity_spec.hpp \ + /usr/include/boost/mpl/aux_/arg_typedef.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/arg.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp \ + /usr/include/boost/iterator/detail/facade_iterator_category.hpp \ + /usr/include/boost/core/use_default.hpp /usr/include/boost/mpl/and.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/and.hpp \ + /usr/include/boost/type_traits/is_const.hpp \ + /usr/include/boost/detail/indirect_traits.hpp \ + /usr/include/boost/type_traits/is_volatile.hpp \ + /usr/include/boost/type_traits/is_member_pointer.hpp \ + /usr/include/boost/type_traits/remove_pointer.hpp \ + /usr/include/boost/detail/select_type.hpp \ + /usr/include/boost/iterator/detail/enable_if.hpp \ + /usr/include/boost/type_traits/add_const.hpp \ + /usr/include/boost/type_traits/add_pointer.hpp \ + /usr/include/boost/type_traits/remove_const.hpp \ + /usr/include/boost/type_traits/is_pod.hpp \ + /usr/include/boost/type_traits/is_scalar.hpp \ + /usr/include/boost/type_traits/is_enum.hpp \ + /usr/include/boost/mpl/always.hpp \ + /usr/include/boost/mpl/aux_/preprocessor/default_params.hpp \ + /usr/include/boost/mpl/apply.hpp /usr/include/boost/mpl/apply_fwd.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp \ + /usr/include/boost/mpl/apply_wrap.hpp \ + /usr/include/boost/mpl/aux_/has_apply.hpp \ + /usr/include/boost/mpl/has_xxx.hpp \ + /usr/include/boost/mpl/aux_/type_wrapper.hpp \ + /usr/include/boost/mpl/aux_/config/has_xxx.hpp \ + /usr/include/boost/mpl/aux_/config/msvc_typename.hpp \ + /usr/include/boost/preprocessor/array/elem.hpp \ + /usr/include/boost/preprocessor/array/data.hpp \ + /usr/include/boost/preprocessor/array/size.hpp \ + /usr/include/boost/preprocessor/repetition/enum_trailing_params.hpp \ + /usr/include/boost/mpl/aux_/config/has_apply.hpp \ + /usr/include/boost/mpl/aux_/msvc_never_true.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp \ + /usr/include/boost/mpl/lambda.hpp /usr/include/boost/mpl/bind.hpp \ + /usr/include/boost/mpl/bind_fwd.hpp \ + /usr/include/boost/mpl/aux_/config/bind.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp \ + /usr/include/boost/mpl/next.hpp /usr/include/boost/mpl/next_prior.hpp \ + /usr/include/boost/mpl/aux_/common_name_wknd.hpp \ + /usr/include/boost/mpl/protect.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/bind.hpp \ + /usr/include/boost/mpl/aux_/full_lambda.hpp \ + /usr/include/boost/mpl/quote.hpp \ + /usr/include/boost/mpl/aux_/has_type.hpp \ + /usr/include/boost/mpl/aux_/config/bcc.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/quote.hpp \ + /usr/include/boost/mpl/aux_/template_arity.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp \ + /usr/include/boost/mpl/aux_/preprocessed/gcc/apply.hpp \ + /usr/include/boost/range/functions.hpp \ + /usr/include/boost/range/begin.hpp /usr/include/boost/range/config.hpp \ + /usr/include/boost/range/iterator.hpp \ + /usr/include/boost/range/range_fwd.hpp \ + /usr/include/boost/range/mutable_iterator.hpp \ + /usr/include/boost/range/detail/extract_optional_type.hpp \ + /usr/include/boost/range/detail/msvc_has_iterator_workaround.hpp \ + /usr/include/boost/range/const_iterator.hpp \ + /usr/include/boost/range/end.hpp \ + /usr/include/boost/range/detail/implementation_help.hpp \ + /usr/include/boost/range/detail/common.hpp \ + /usr/include/boost/range/detail/sfinae.hpp \ + /usr/include/boost/range/size.hpp /usr/include/boost/range/size_type.hpp \ + /usr/include/boost/range/difference_type.hpp \ + /usr/include/boost/range/has_range_iterator.hpp \ + /usr/include/boost/range/concepts.hpp \ + /usr/include/boost/concept_check.hpp \ + /usr/include/boost/concept/assert.hpp \ + /usr/include/boost/concept/detail/general.hpp \ + /usr/include/boost/concept/detail/backward_compatibility.hpp \ + /usr/include/boost/concept/detail/has_constraints.hpp \ + /usr/include/boost/type_traits/conversion_traits.hpp \ + /usr/include/boost/concept/usage.hpp \ + /usr/include/boost/concept/detail/concept_def.hpp \ + /usr/include/boost/preprocessor/seq/for_each_i.hpp \ + /usr/include/boost/preprocessor/repetition/for.hpp \ + /usr/include/boost/preprocessor/repetition/detail/for.hpp \ + /usr/include/boost/preprocessor/repetition/detail/limits/for_256.hpp \ + /usr/include/boost/preprocessor/repetition/limits/for_256.hpp \ + /usr/include/boost/preprocessor/seq/seq.hpp \ + /usr/include/boost/preprocessor/seq/elem.hpp \ + /usr/include/boost/preprocessor/seq/limits/elem_256.hpp \ + /usr/include/boost/preprocessor/seq/size.hpp \ + /usr/include/boost/preprocessor/seq/limits/size_256.hpp \ + /usr/include/boost/preprocessor/seq/detail/is_empty.hpp \ + /usr/include/boost/preprocessor/seq/enum.hpp \ + /usr/include/boost/preprocessor/seq/limits/enum_256.hpp \ + /usr/include/boost/concept/detail/concept_undef.hpp \ + /usr/include/boost/iterator/iterator_concepts.hpp \ + /usr/include/boost/range/value_type.hpp \ + /usr/include/boost/range/detail/misc_concept.hpp \ + /usr/include/boost/type_traits/make_unsigned.hpp \ + /usr/include/boost/type_traits/is_signed.hpp \ + /usr/include/c++/11.2.0/climits \ + /usr/include/boost/type_traits/is_unsigned.hpp \ + /usr/include/boost/type_traits/add_volatile.hpp \ + /usr/include/boost/range/detail/has_member_size.hpp \ + /usr/include/boost/utility.hpp \ + /usr/include/boost/utility/base_from_member.hpp \ + /usr/include/boost/utility/binary.hpp \ + /usr/include/boost/preprocessor/control/deduce_d.hpp \ + /usr/include/boost/preprocessor/seq/cat.hpp \ + /usr/include/boost/preprocessor/seq/fold_left.hpp \ + /usr/include/boost/preprocessor/seq/limits/fold_left_256.hpp \ + /usr/include/boost/preprocessor/seq/transform.hpp \ + /usr/include/boost/preprocessor/arithmetic/mod.hpp \ + /usr/include/boost/preprocessor/arithmetic/detail/div_base.hpp \ + /usr/include/boost/preprocessor/comparison/less_equal.hpp \ + /usr/include/boost/preprocessor/arithmetic/detail/is_1_number.hpp \ + /usr/include/boost/utility/identity_type.hpp \ + /usr/include/boost/type_traits/function_traits.hpp \ + /usr/include/boost/core/noncopyable.hpp \ + /usr/include/boost/range/distance.hpp \ + /usr/include/boost/iterator/distance.hpp \ + /usr/include/boost/range/empty.hpp /usr/include/boost/range/rbegin.hpp \ + /usr/include/boost/range/reverse_iterator.hpp \ + /usr/include/boost/iterator/reverse_iterator.hpp \ + /usr/include/boost/iterator/iterator_adaptor.hpp \ + /usr/include/boost/range/rend.hpp \ + /usr/include/boost/range/algorithm/equal.hpp \ + /usr/include/boost/range/detail/safe_bool.hpp \ + /usr/include/boost/next_prior.hpp \ + /usr/include/boost/type_traits/has_plus.hpp \ + /usr/include/boost/type_traits/detail/has_binary_operator.hpp \ + /usr/include/boost/type_traits/make_void.hpp \ + /usr/include/boost/type_traits/has_plus_assign.hpp \ + /usr/include/boost/type_traits/has_minus.hpp \ + /usr/include/boost/type_traits/has_minus_assign.hpp \ + /usr/include/boost/iterator/advance.hpp \ + /usr/include/boost/range/iterator_range_io.hpp \ + /usr/include/boost/iostreams/detail/streambuf.hpp \ + /usr/include/boost/iostreams/operations_fwd.hpp \ + /usr/include/boost/iostreams/detail/adapter/non_blocking_adapter.hpp \ + /usr/include/boost/iostreams/read.hpp \ + /usr/include/boost/iostreams/char_traits.hpp \ + /usr/include/boost/iostreams/seek.hpp \ + /usr/include/boost/iostreams/write.hpp \ + /usr/include/boost/iostreams/detail/optional.hpp \ + /usr/include/boost/type_traits/aligned_storage.hpp \ + /usr/include/boost/type_traits/alignment_of.hpp \ + /usr/include/boost/type_traits/type_with_alignment.hpp \ + /usr/include/boost/iostreams/detail/streambuf/linked_streambuf.hpp \ + /usr/include/boost/iostreams/operations.hpp \ + /usr/include/boost/iostreams/imbue.hpp \ + /usr/include/boost/iostreams/input_sequence.hpp \ + /usr/include/boost/iostreams/optimal_buffer_size.hpp \ + /usr/include/boost/iostreams/output_sequence.hpp \ + /usr/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp \ + /usr/include/c++/11.2.0/cassert \ + /usr/include/boost/iostreams/detail/adapter/concept_adapter.hpp \ + /usr/include/boost/iostreams/concepts.hpp \ + /usr/include/boost/iostreams/detail/default_arg.hpp \ + /usr/include/boost/iostreams/detail/call_traits.hpp \ + /usr/include/boost/iostreams/detail/config/unreachable_return.hpp \ + /usr/include/boost/iostreams/device/null.hpp \ + /usr/include/boost/iostreams/detail/buffer.hpp \ + /usr/include/boost/iostreams/checked_operations.hpp \ + /usr/include/boost/iostreams/get.hpp \ + /usr/include/boost/iostreams/put.hpp \ + /usr/include/boost/iostreams/detail/double_object.hpp \ + /usr/include/boost/call_traits.hpp \ + /usr/include/boost/detail/call_traits.hpp \ + /usr/include/boost/iostreams/detail/push.hpp \ + /usr/include/boost/iostreams/detail/adapter/range_adapter.hpp \ + /usr/include/boost/iostreams/pipeline.hpp \ + /usr/include/boost/iostreams/detail/resolve.hpp \ + /usr/include/boost/detail/is_incrementable.hpp \ + /usr/include/boost/type_traits/detail/bool_trait_undef.hpp \ + /usr/include/boost/iostreams/detail/adapter/mode_adapter.hpp \ + /usr/include/boost/iostreams/detail/adapter/output_iterator_adapter.hpp \ + /usr/include/boost/iostreams/detail/is_dereferenceable.hpp \ + /usr/include/boost/iostreams/device/array.hpp \ + /usr/include/boost/tuple/tuple.hpp \ + /usr/include/boost/tuple/detail/tuple_basic.hpp \ + /usr/include/boost/type_traits/cv_traits.hpp \ + /usr/include/boost/type_traits/add_cv.hpp \ + /usr/include/boost/type_traits/remove_volatile.hpp \ + /usr/include/boost/utility/swap.hpp /usr/include/boost/core/swap.hpp \ + /usr/include/boost/filesystem.hpp \ + /usr/include/boost/filesystem/config.hpp \ + /usr/include/boost/system/api_config.hpp \ + /usr/include/boost/filesystem/path.hpp \ + /usr/include/boost/filesystem/path_traits.hpp \ + /usr/include/boost/system/error_category.hpp \ + /usr/include/boost/system/detail/error_category.hpp \ + /usr/include/boost/system/detail/config.hpp \ + /usr/include/c++/11.2.0/atomic \ + /usr/include/boost/system/detail/error_category_impl.hpp \ + /usr/include/boost/system/detail/error_condition.hpp \ + /usr/include/boost/system/detail/generic_category.hpp \ + /usr/include/boost/system/detail/generic_category_message.hpp \ + /usr/include/boost/system/detail/enable_if.hpp \ + /usr/include/boost/system/detail/is_same.hpp \ + /usr/include/boost/system/detail/errc.hpp \ + /usr/include/boost/system/is_error_condition_enum.hpp \ + /usr/include/boost/system/detail/cerrno.hpp \ + /usr/include/boost/system/detail/append_int.hpp \ + /usr/include/boost/system/detail/snprintf.hpp \ + /usr/include/c++/11.2.0/cstdarg \ + /usr/include/boost/system/detail/error_code.hpp \ + /usr/include/boost/system/is_error_code_enum.hpp \ + /usr/include/boost/system/detail/system_category.hpp \ + /usr/include/boost/system/detail/system_category_impl.hpp \ + /usr/include/boost/system/detail/interop_category.hpp \ + /usr/include/boost/system/detail/std_category.hpp \ + /usr/include/boost/type_traits/decay.hpp \ + /usr/include/boost/type_traits/remove_bounds.hpp \ + /usr/include/boost/type_traits/remove_extent.hpp \ + /usr/include/c++/11.2.0/list /usr/include/c++/11.2.0/bits/stl_list.h \ + /usr/include/c++/11.2.0/bits/list.tcc \ + /usr/include/boost/filesystem/detail/header.hpp \ + /usr/include/boost/filesystem/detail/footer.hpp \ + /usr/include/boost/io/quoted.hpp \ + /usr/include/boost/io/detail/buffer_fill.hpp \ + /usr/include/boost/io/detail/ostream_guard.hpp \ + /usr/include/boost/io/ios_state.hpp /usr/include/boost/io_fwd.hpp \ + /usr/include/boost/functional/hash_fwd.hpp \ + /usr/include/boost/container_hash/hash_fwd.hpp \ + /usr/include/boost/filesystem/exception.hpp \ + /usr/include/boost/system/error_code.hpp \ + /usr/include/boost/system/error_condition.hpp \ + /usr/include/boost/system/errc.hpp \ + /usr/include/boost/system/generic_category.hpp \ + /usr/include/boost/system/system_category.hpp \ + /usr/include/boost/system/detail/throws.hpp \ + /usr/include/boost/system/system_error.hpp \ + /usr/include/boost/smart_ptr/intrusive_ptr.hpp \ + /usr/include/boost/config/no_tr1/functional.hpp \ + /usr/include/boost/smart_ptr/intrusive_ref_counter.hpp \ + /usr/include/boost/smart_ptr/detail/atomic_count.hpp \ + /usr/include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp \ + /usr/include/boost/filesystem/directory.hpp \ + /usr/include/boost/filesystem/file_status.hpp \ + /usr/include/boost/detail/bitmask.hpp \ + /usr/include/boost/core/scoped_enum.hpp \ + /usr/include/boost/filesystem/operations.hpp \ + /usr/include/boost/filesystem/convenience.hpp \ + /usr/include/boost/filesystem/string_file.hpp \ + /usr/include/boost/filesystem/fstream.hpp \ /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/HiddenLines.h \ /usr/include/c++/11.2.0/map /usr/include/c++/11.2.0/bits/stl_map.h \ /usr/include/c++/11.2.0/bits/stl_multimap.h \ diff --git a/build/CMakeFiles/linelib.dir/compiler_depend.internal b/build/CMakeFiles/linelib.dir/compiler_depend.internal index 3367adb..34e0779 100644 --- a/build/CMakeFiles/linelib.dir/compiler_depend.internal +++ b/build/CMakeFiles/linelib.dir/compiler_depend.internal @@ -5,17 +5,4 @@ CMakeFiles/linelib.dir/src/Line.cpp.o /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/Line.cpp /usr/include/stdc-predef.h /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/Line.h - /usr/include/c++/11.2.0/limits - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/c++config.h - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/os_defines.h - /usr/include/features.h - /usr/include/features-time64.h - /usr/include/bits/wordsize.h - /usr/include/bits/timesize.h - /usr/include/sys/cdefs.h - /usr/include/bits/long-double.h - /usr/include/gnu/stubs.h - /usr/include/gnu/stubs-64.h - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/cpu_defines.h - /usr/include/c++/11.2.0/pstl/pstl_config.h diff --git a/build/CMakeFiles/linelib.dir/compiler_depend.make b/build/CMakeFiles/linelib.dir/compiler_depend.make index d84048d..10d2aae 100644 --- a/build/CMakeFiles/linelib.dir/compiler_depend.make +++ b/build/CMakeFiles/linelib.dir/compiler_depend.make @@ -3,50 +3,11 @@ CMakeFiles/linelib.dir/src/Line.cpp.o: ../src/Line.cpp \ /usr/include/stdc-predef.h \ - ../src/Line.h \ - /usr/include/c++/11.2.0/limits \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/c++config.h \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/os_defines.h \ - /usr/include/features.h \ - /usr/include/features-time64.h \ - /usr/include/bits/wordsize.h \ - /usr/include/bits/timesize.h \ - /usr/include/sys/cdefs.h \ - /usr/include/bits/long-double.h \ - /usr/include/gnu/stubs.h \ - /usr/include/gnu/stubs-64.h \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/cpu_defines.h \ - /usr/include/c++/11.2.0/pstl/pstl_config.h + ../src/Line.h -/usr/include/c++/11.2.0/pstl/pstl_config.h: - -/usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/cpu_defines.h: - -/usr/include/c++/11.2.0/limits: - -/usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/os_defines.h: - -/usr/include/stdc-predef.h: - -/usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/c++config.h: - -/usr/include/gnu/stubs-64.h: - -/usr/include/bits/timesize.h: - ../src/Line.h: -/usr/include/features.h: - -/usr/include/features-time64.h: +/usr/include/stdc-predef.h: ../src/Line.cpp: - -/usr/include/bits/wordsize.h: - -/usr/include/sys/cdefs.h: - -/usr/include/bits/long-double.h: - -/usr/include/gnu/stubs.h: diff --git a/build/CMakeFiles/linelib.dir/src/Line.cpp.o.d b/build/CMakeFiles/linelib.dir/src/Line.cpp.o.d index bdf6cbf..9fa47ca 100644 --- a/build/CMakeFiles/linelib.dir/src/Line.cpp.o.d +++ b/build/CMakeFiles/linelib.dir/src/Line.cpp.o.d @@ -1,13 +1,4 @@ CMakeFiles/linelib.dir/src/Line.cpp.o: \ /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/Line.cpp \ /usr/include/stdc-predef.h \ - /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/Line.h \ - /usr/include/c++/11.2.0/limits \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/c++config.h \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/os_defines.h \ - /usr/include/features.h /usr/include/features-time64.h \ - /usr/include/bits/wordsize.h /usr/include/bits/timesize.h \ - /usr/include/sys/cdefs.h /usr/include/bits/long-double.h \ - /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \ - /usr/include/c++/11.2.0/x86_64-pc-linux-gnu/bits/cpu_defines.h \ - /usr/include/c++/11.2.0/pstl/pstl_config.h + /home/noah/Documents/School/CS-7353_Analysis-of-Algorithms/HW/HW4/src/Line.h diff --git a/build/libHLlib.a b/build/libHLlib.a index 680b9cbb96f7b4d53eb9bc54de270f957ec83fc4..c28bfef6067baeb74cd11fedce6c51185e8cc0f5 100644 GIT binary patch literal 57420 zcmeHw3w%`7o&U`XB4{R2RI1hvbhL@qn1p9QZ2}40!3jnJLPeasCJ@QXWD)`@Mw3v+ zAxc}@TI+79kCxh6v2|UFsNo@?wOwjkwbrfFx=K2zELLUJE&uQDJZ64#=iX#u+kJfg zdp?=mbHDfZI=}Nfk9+QG(j_(Rb*nBLcd;94PN{<|~vM|2AwzQ|bc^HJwdCEv~htzA@O?+A^%=jV-}I zduyBKQDt_t-0GZBDYY^e76h*EZ0xFO3bX{v8y8)^u&TgcI8FI5YJH;nhLxkl6lgK^ zfnmyDSkw`$kJhwfsZ~A4Q_pA)bad3L49uBU*WF!Mn6wsasjGqsWj4x|=C=nL^8Nmm z-QE7SKzm1POHET_aIL?qfZP!muiChoItUTC{#C6_^?`P8SNY7wmX2UeOI@HGjEk?b zXN~iMAoM0lm;_l_k!%9CM#pI`D@>ZQVD!yO*H?LCWnFV(P>s-*ljDw$kWn=bU5#-b ziHns*mm^eIT#F9L&Z{#!TH4ytup7!z(#p&0)(uly`}RLVX{`+~fxO7{6|W2g{Y{N6 zfeu+!#R%q>PCvDkBELV_>hJCd!pN20g;l{Bet{Pj7S+~tpc_?3>QLUox>Ysp{$P7e zW3aN2G&#YK5>nX+*=jdk4n0ZlMvuA9NJ27 zsFT7O@JM^0rm3m5&W|oE&>r+IKm(xqD(_mzf(fzH(%Rl!(-ifOw-RJkMW8HeyJE3l zR_{#zqFRJeK-VlNg2jGsJ%%3it0EApf>WE&rOUjEjhQe5UhfE$SEBN#XdzHp9}t96 zx{j-Q#8iEGxvllUN4C7asxaPei{zL+Bl$o|`l||GI31;z&i8k=G+y5s@Tw|+tJ-QB z+r99~jHpj^d7Ob0NnIncf`;1G<6CGsO|oPjZxx{`7`QB-rFTU-@CC|Wy9yYbbQ z#v*5g0m@EnGAs^S>^p(slnle+prgos@EK0Ya4hy(;)i4*+kO`0G>adOWtcKMDH*2B z7M8@IxY&AP$Ik2QvPIDozv^*jV?8=M8uvQ#>)P7#TQ43r?&9ci$<2598RGP*^7L@p zlo>@c1!?uTo6CLkQd3gWaK0!~igB5dqIcMK%huRViO7~14;c3g+G*G)o*DSfRQXxh z;sjLSm#FP!*nUCfOVqYhZRe=%T(vF3wp``sVLKl`Q|)`PU4Y-^`1ur8f$c(-zXIDz zmA?|(Mfg>z{l(ZW!S5=yzZBbLDt|S$%T;~_w%6k4SNql2)~I|vwgHu2iR~(tZ^ZUG zm0yi*lgc+^+oJMq*j}&l?bvpxd=T4CmG8oKjmmdpyH@3I!1hL!zgca2u)Rg)Z&lk~ zZ2MHcUu`#F`z4j%sJ0<&Z&UfO+HS&jK;>`8_70WbjO~|I{wvsiRpsx*_G>Etb!@+( z@^@kTO_l!^w)fyyx_C*I8T!Z@`m-5s$uuv_H}{VPY?%A!XR2*BZC!moA$0qp6C&Mg z7C-I!5-B%B?;IuqGqlePO)*0qnP$p+W@vS`H|+Cddc&7^%;NtDUTcPqo1tUxx>^la zPAWELwku~rHZqlNSI#20*}J>I>>VsHi+6RtYz~wjH1m#|yAG$DJAUw>NaIY`!@JEL zQu_&)Iq9G|P*##=?mCoira&{)hF)5}qV$?QX8&7jGlWUv-;-qAPz@MMmzG{txR144uuUhG*V3MEOlnPFG~XL#Do;{CxaGfcUGwiI!g z4wlftN*r|c4vwK!QHNe9OKWA;8>;4N-OL{Q5^ysj`@dDnO-as%0} zyn2rtxn{R3ugOyoiwxB9`aQH;;ushd2Ja#+M7+3e`|f|9IN|Ewg8zc8bbGoe$iGu{ zo3ZL1T2B3L;+j{dt8ONQcnz!tw$fkx+x}x;jQvV*|nYhs3j?gwk{}~tk zTY(i0?l1G?f*Xy$%u^sTh@4zAROXpU|4IlqC4p@xVeU`&X#Px{5#5J5aF1sT5OZLs zXA2@uSY-}m2%=D*z|8%9o^IGdX{Lo{$(`q9$fOFV|;Ci8nhA?@a6F=@1f)NC{FFJ}J< zSKl|#$_3fb0JV4CH4iLCFCKbR9F2V13}>6+MTg%n%XVjUo^ST$o}yWXcza@{_O@Qfr0)wH7`{AdOROhy0uH0@ZAB2Pq-yF`h#+{kA{ z&GXO#w)bvvLCh&lkYGSa2`3q5ANy1MAF$V6&BB9eron;;A~5TfgW??kWt`)Jn!m-A5(Jt0l8 zVl%bV&Cp>?)@Uwfovdxf8CmZUOf)`XQ?xSAM4X-2pPOMA(7n1Do^6IZU{1Qn45d*# zU`U#qNttY9vWJoIpb zLDC6{rQLzP%#j|w{rabAR)JFi*`3HU#-U494_JbhiE5IFs!Zu7#^%v~R*dtDFz z#vEw>i`n~OifhBeP=eNa4UGxQwjfvUsdVL3Z=*AWYBN+h=z0uih8rsnm?UJN?O?Q0 zVnTaAEO7O`PS*B6A8d!ORvn}>7xG%$Ay;0IV%9urhI|-<9y5<`^kHZRPnRDA-CJCF z7?6l*8!=Uy;mScX1m&*BN)Bu+^Q;o3q|Qd39!KV>F_<~e!Kq1mP|kOx2WcGrd4ua> zoL_gHCY`9qr=k0((^Ns?>bn~yroMKn$CWdkGB6PXs~BUip@H{W87|)5eFYW89|Uiz zpyd!<6|TMrra$B&I1A03d;w>nfg`u{?&}+J?hSrG=7oB&knW3k62|WchAZt$%*TS}fz#BT@4ZXlxSf7VZ2dR;v z13(U8iZ-k>ZjlL}Ylbf{XJ3oq>M@*kdPDCG6(TlihVlyByT`TRHWjMXB1myy{a&hO zIpZg~UmtT_a}c$HHI29fl1{O?at{#gUeNABb%FMn>)He^c?5cQcQp%H4X)hXvT;Bq zmRq8Y1xd9Cs5|XuQQO$a&yG z)c0p81PYK@olT8}noWnB!iR$4CWFGK8o3G_^?BNmTY;nU1SRIdp@Y;fVS2}w79zLB zjz?=ES}`rpVM*b@x^p|viBXk?L~Ti$(&D|HC(|*x8#y~hXOR|}5CvpK57Fuo)!?sD zI|p4GXqiz+YH+XB%)I@EgS%x|aSCK^hsQD&3Qt*owwVqsZr*g?v(JDgq9Qv3B&^Wh5-iSt(jKHBg zKLSzcW!-g)HdVYLlg>4DgABfk267>tAE6axi?btF>kV#sZbTIjdB!`tB{R6d9Kh5% zf*$ivx<{4kcQ}@B5!a0RBYB-#-c4NI0qUr;^}?bVMy*EYL+;otNp`QXzIv7q%iOo@ z-HPa7eYIGG(Q%;-^HLeV=^Lo`WDlK+P!ZJ_*P$PW6s*(H(tPMwaeX?`qE8Rc%N%At zci|YE9=ZBXroKD6Z11II`#*tQpX!KZdz`L@aJsr+AU&Vf`J9&SGhI33;IT@0Y*98c z%iyuAQQv>%(mgc$FjV6l8pCcy-VtBukh$x4Z0Y|&TKf0)eq6n#!qt~eJ>vdylt64V z)mDye{e!MP7tR%QEDe>RGp?|^9*{{57DJ(1@+Yi&;!ue`Wa><%$o%p!^)1It*9C*e zT%R8_@A3_JO1!&XPp?QhQc?VGL7xwyxd|vcb6~#w_g%pFiG{zJJ579gX z13}JZlqrW#=ZX19EDUoCBKv%^>oS8^_y#b7L{7&{4(6KhXv zPZ5rzs~Q97tke#!>Crh~XQnsh&%RIqv2i&9Ww!0b#BN0TI_ii&pfpPP!-Zyf|EC4tyH2P*3vQ*&H}s?*85k zUrISawR}(i`>wAI?ooHqqHUp%HjF*;7Hw*4azAuboO$oTjl;7#TUNKUu4#!LGeaMS zj_$#w>R*}Ru_r1sL%X(t9ndXitRD2MG%l9y%;yIbb8!?L)h|Fs!;lGDoFvF#o1`MK4 z>ph+lbPEe+=LA>n>3_cSBXj#NwT|NX#I;8pH+MWAg_mY_{@M($h3=nZluV#|C+M>H z2RQvZZsr{{e|gwU*=_Fn(*(2e`43Kf20iABjVBJ{%p$G0_yZDXhOa~$fbF;tG1e@8 zQD9QpP&caAz`79#ZpLry2^hII6CUe5l5Jf|%B0Cd7pTUZsB}~Bn;8qCljwA_cW?G` zb>&cAFvoh7H}r972v_#`R0MM`5_MgsS^Q40Lq-f{7;=e0t*~)F2iKYdi&D(ugS2QW zDxHe5{HbhIrQ{BwHCEtHp$QNP$9OR$DY<2# zw;?)$c_{@TT3Y1Za2l!B2HTO->I|)!O%OL4bY2A4V$F=M&hGJs(>;)hzVJk4uBigr zEUwDze71Nzg`cc}6DLw+y=paMrKe==Vo5C?f0BHu+arP+5fS>pMC^v1jq%x|;?@Wi zJyby4O7VQ~W;67gg!Te=?ubSE!C<9tfO_a9XdTaYF5%U=J8E948M;o@qu2Eax%cVd z1!frVi^83MikzcDV0YxyXilw*g?6jEJIEW++cc#Lj+OR(lw1@LtIe81qat-gShYvKVfDbI>+M+)q@HP znV6&@6w5+?I#D@s=p2lk{l7ym8#yQnOQW*5AV)X(V32k7<$}T{_VrMVhUn^}OE$i6 zb!PbNB&>98_!(r6*3w9)Y(JRgi&Ny`RGDeAD6xsa!@BZzirK3*{84`sp#bMG=>?={pwDwiC?wwu;KWCSlNtJhY-tz+ z*vft;&SA+s*#Rw)L$O=kUg;K(|G3YqH>yHdD#o?2Uxaq){xtNeD6$laCc6hxjD@Xk z^+1n180ZeVYr61cS50kGz>WLwW8&n!XuU@Y(Bs4vCl_N(|1-g*rF16zGqd+UQi7+! za>P;Sm>K$u8TuCtW08z~sYYaqIZ%bGu^zONH}nOAePy4<$cQp$qd^37XuQj&`=6qb z4?eo>Y(sEf^QLhr;%DGo;-7aNrI#J5gK$(WV))sz%8C8Q;0 z=-=q3vnunJBSa(awS(2vANxZ6l?XOpXkZyOsQmL?dHr<3&XqUNCN@iYTzM-tyYd2C zTzSpgTzQ>?uDqKLGUxQ?f)4H(n0Kbxd+4Z{x0lWpUEbb*JG#F=8^_$xxxaq`axx5X zk`?Noh+T7_zkoKOez({gAZnammY#UtS9i!9xB-N-eW3^FOc^KNt~Dk2pVHZci>2kp zMqEh>_luKgadqjmed(zN5V9ub$@w&u7zi9*PQx9p6Ak2E}Y-;DDbjEfpu8Vvf;t+sA&ncHyV*7HUYNbR@@tNT*J9c-mde*VSv zHNhJ3FTbv%%jgKU)=M_Sy{e|e-O<$A765-uOTD|sy%v)31V~+=E$D7-AeR|vq?3Jl z&tw=6r3|F*NHcy-UC}FPpF#GG^jwSt85uZ8^ zJ82mk#u;y=gXD#b3tr1GJ{+^`#2Dk{vBk)5KIyBOIQpBMj8}40n2^44(=#4UF`h^P z5B5%-w>jm76ytT;y(RU>>Bs{efBgq1eQ&(+&*LRgelxbure=J6lJVQrafb1H+V@kw zdx{ax$oS4F#se7{hfX%`9{Wxz4&QSMC{aaYY5qD<&J%ILI1lGFGQtt^nR`TYHTaW4 zvu5$0xT&6-tgTO3)A(&y}TKjxo-XBejUS{t{t~K+} zJ7Z4sQA+13gj2d_<5)9HQ#e`*SYpUn0(&fyOjwsK8zj3a0Rx~4CVdMkf{E4@ge(|^ zMMb%|5&1UVAab_~C2@V#6jviZ2))2s6Yg_^$zl@uQ)(_^UWSWzi1tvLyhhdk7A}hF z>EgiR3^eGs^=ylJmYFf5$H|$riA$uicYt1b<0({!USxXZH3(Au#*QB7737#7jY6{& z5mOE$>8jCPkoG@CzkEPU1XTRvM_5OQ-I^=TG+s2rtymD8fv(t>cQkP|(A**K3Vtw^ z&Lzrmqb??ah-_I$uJVI8k!qh~ZjVvzHeK^})0l^8(@~O%Y4%3k1fUaC%k#0{#VHKJBz6}}&wjO(@&qfIRIsu^CM{bVI7L$-?k z-*x_;`YJ?qT-1PND!P!xw3xgSzl+JYd4Ixn^fYrjh8;>StO*2hE9*x%O%bP z5!HY8uFgb7(CmlY8{aB3asDrO{n@^ORxCmMuG8%cMSQbcCw7)pgx)TFiY7dfl~`_> zNau~8qN(9Phg%EB^yYOO%Z|K;yH)$>+MyRW5l)o%RqGzqi%CA+v3dj8L;vpZ4s=CrFAeRF-0njU118vFM4qAlMmfFA0Mlak+^VbG4S18m zEce3B=Gs6zO(NtB1J6LVHwHS~^{x0v<7RVBux^z*xGI35RFm@QhhoTgLw;pb0FOty z>ss5}@%XG@(wfA?CD^{!U9+;Lu_d3ZF^r4iQ&nqwFi`In&n3BQ*Gh|K#nW75!)Kvz z*aai+&}&*&2K;ra0(Glrx$)SjJ9o{hMijKM!+qYm&OG;Jm%{wUj*BkqXj~V_&9fXf zY@!oAS7LM)u;?Vq?bApP3EFeT(0Kk4pY)3{CYiIB@ASZ1l0q4oy?n>#`xs|(SzGzm zhXIol^?y|Vg&xog-dd#`^4?J+-#hg9noRTO&Yk7XoxgBNp1ZIxzbK#P!brH7YPj*E zGYK3tQjL^B!sMAQZRP$+z$i_S8zW`iA|s_cJLT+?$7a%<{n^0JQOD@1AxeZPHAbdD zBvz*K99w3C(Q|#2I9-oG3`6T6oiy-JqUZOF(yZ*>)YRqUvNB8Qeq*xXQNocPkQ-5k z11f(iZOgKViJQ_&v)mifOS5u&Gs?0m(-x$R%gO~*nl%w5b4UaEw_Z7aBJsku zD%eK(8x=m8aA8|Dj>tN>OC6(Ir-|oE93ffTY;byHK$ri1jrf00dDW(Pg7Dlz^Yo z59#0htV1cO-xgIx$F5PwJakNyuU3?ADt5b7Id&nh^>cfnHFd){;Yw*XYM;uvP05TP zPxZigQlA~C3n^lS^d3_5UeX6i8&c<D1l+)d<<4P#2PX7-MqpLH-L?PYjnCNMY#G|VxOM|E{g8vY?oqJKVF@6>*R z3V)1nOBu?t3Q_}>a_53Fj6g%&LmFlHi$(n_HTzTBri#kMU=-QjH zMbUje8J(4Brwym`h>|rWLFaXGIww%)iA0ZGj#$o;)Rfa0oJ>3j$suE-AWxA|E| zGtxGl}ne;T2$j0ipEUP5-yR3?ZuU}W?8Lr%9>&c3)7V(pmt%E6PrD@K# zit;O&zr;2vnTJx+!WqNMd{oKYhCw4KncGs+W{q){NqtqOcv#XfM4Ny=ds7=kUxh=q zi9#dY`1ccb2h)r~JJ?7wsOL*eX~wif5J;La!vPnqCgE6`L8Db-O2fMe>{6OhVh2NS zsRKU80iWxDmpS0`9B^v!i7CzSCW1iH#G4Ef52YCuiJ+jr!U4b10k3kv7dzlrIp9kj z@T(p06%M%H0k3wz>m2ZU2YjUi-spg@cEFn*@HPjW-sq5+(u`mt2qewua=^PCaC!qo ze9FOYD%$B~=Sp0(dt@)fFNL*JYUh+>i>sA8?Ee=;z7{scCmH#7N9VfwsEp)V<75q} zt&Ggt1bP{1wT8IP$#`Vs)EehAjIz~Y|8DW0{|ktnT0<-*umiFNYZH2i>jlj^Mk%vm z{$Z?BdSZufQuLc+kjV8a{D1`yiT&DymVJl9msse(rtrBIT+G&CPxJ&w9siElPPb4S z#&-o$oPhs8AmYxIxMSPI-WTIA+W9AeT$6zB5J*D;J}8jZ1bm-BtkGZ?M+I)Jb;CFV z0XdnC7h{yfQh~?Di%f;D75FT*7d!W&^N7i8ywLO?2|PAlXnYFh#go~1q4l;2yfi9b zoU>t%9-5nM%!%R;s2t6&CmXR^6z6L=mX}6&Y`iE@^fkbxRBK)sZxoaKhZxHmGqV!t+{SNfI z9Pm93_8$cOWY&tb{0|-EOvK#Dj((27FOS+eS>>95+xb5z=wsvT8H)Z92l}0YJ~sYp z`VR#j8-MRtaxOuDO*UfVES;xPx<%lz@$`ohHXa0SXXm4W{%S=PJC{Eu@Yp!JOHoY1 zJkU-~o&!GH0lyshscaq?QSz^Kpug1t{}%AcMs?JFaUP4k2?%UEJC`}&e&A$}wu9Os zr9KDxe{jHm;($NlfR8`P-p<7i_(})-dI$U_2mEUe_-`HX!w&dKxMFYT=QADfBH)va zdg)yJpQLij9Psr5Um2x;Oy%Bike@c5$i9Kh}D^a=XaQF?KnkG%nb$L47o z{}+L`Md`)4KK7VlU@3;FHd7{LCzSy}yWQylPG2mFi)_VRli=)dBCZ*jnX z>43lKfFr1E%X@|cUf_V64tR$He!BzyxC8D+jZpmGiFQM2zuXwlf!+>(5%^>yc0Q%s zspm9FzZ~&SiPn%PRRFiE_cjN7gOc+E{7Q+|jVOIz;kTbD_i62i(k~t43=yuzI7uo0 zzwbbw6_^`>?=6QC!o%Ch%|+KTqYxW5PDcxIK!SDtDQ{Hz(k2 z0{=<^exJbaOu+X8cSq4!=4Ie^@ncwC=xO-p`>vQ%>ht?MI&1x2zkFe>dcST}&^OcX zZ)|OBX$%_qzPZ!r-wgUUll~PJ(EnnQEfoKY=>K$)6|{viFIWmCk039aLNrB!sYoyt z30Xx`2^U#;jCKXBI8Z3Eg;VLZx^{0ckH1b^Hch@Sc!bw)E2{tdn#2En&4Iq#@mGJ% z0k5I2sauWvMOORi6Cf0;@v$}XEBo%;dJ&v2k|8m*$Qmi zOA;S{XjwyFJxKZ!5O^iNuwt6}Mv49$iZEhvvfqaQp^{_ystVq!?5|&o52WCA|8+GT z!6bVE^}29-nff*TwjPT6uEMClG*RDF*)_~ZBkXUB(J#E0U!1_p{pB}F+8raw=@r!R zf|85F|2ZF@=+d8~7^d9zZ^a&=+}0Ol$CJa~Ep=^c5odMXHU8Sb%ElJ@(o5Ycg#=o} zmtSaKyxZOK!3unN0YheRReS3id=aAFU(?=Rv)11dSmVd%YE}kU(Pw?c>+d-YeXc-! z?}vS$;J@^17oXr`8pU+)JnnT42Fe#THyh1?X5qCYKbcu9X@A${!w&pG(vRq7$s zT;z&*^Q!Qrj>V;OeC6~GeS9~duCQPZry@L==74|>yn;S_nZzoPa+ zAie`pHQkRde@yX zC=+$3=*Z-!zmz|#g8vIYl!7jcKJr1;81td}6if1-4f&t)!4%nin}X%2W7%gGM(f01 zA3#^#jQg+Yb2KrSK1U`Z3k2q0bxQvB`FNa8gA6RNc4XgFp1}AEs?9F^ZzS$nhe{m{8^9oh7C%{?-P6 zJ3T|7gvqHw2b(Gg1YuGy&0#IHu|+prsy+LbyHGZLF%cC{X6VtKrfBLTSon(6qN-N; zRVzlmmL3b0Geo`v#Ap*})WHNr(pNuu&egiYirUkNETtue6~NjcN0 z{+a?hqW-%-0EMcK#tyG)e?v3Hj`)P0@E^{!F*WQ6)S(`zd;S}KISSs5cCJ&snBB<^ z$6w#k>R*K}yh-&O@kG*t;v@(CLpK)qP^Fe{Az9CqLJXW zA*Le!x~7_r4nNIC5t0pfq$yF`h!3NH#iBeJmUvre8q?7@8guL?b9S!K)(pd8aj@oa zn0XGTWH=UkE%B?PLbm18QBiaB5|Uhbh_2yKr8%$+Q)UN_;R;}3v57GexNV*70rXbw z!Oj}F&St;BgIKKaCwz8Qu9cUoC3D>NA->auw>paS62n`N*Z99Oyp`dT)qON{>EuF& z=P~^A44#>B86W7jIM5Lz1J}MHilovyo=%AWb*0S zxTb%I(bF{$jqhai-3bvtuZL54IX+%pYa*QPfzt9PD4aIj&QCG=b&Nij(HAhh zfYI}E&2hl5WO53boG&`iuXe!iW;k8-)8+aO!*68xj~Gt(1ZsM^AB+m-xa=qr-48~I=m$RD5nZoGX7(LyUr{#Q=;rB3H-`h`mIlhb0 z{{y3cf#Lti@Cd`d&G2Ii*ZxuNGBVWlWQ}XTxf#y=KTYApzlF)al;O8B+{f@u3}4J} z9{*1;{5y<(FT;7e`!&OPdoghT7$vgvUi`HGKgIC-7=Dey$q!Q*Uc>0`XZVc_=j}Sg z@CO+EeGIQ=_`?df>V1^af0xnkV)y{V-(xuU+a%ndMv44Tji2_z8iwsL70GmX)2 zVmR;5zs%(D{+aHhqeOD1r^SCOLv*XAdjaSq%Rk!#xb&%J3-+-^}nzhTp;P>m2a)4F5i(*Y|UgoewhnIYxgQ!(Uc7 z)z=J$|AFDWzTRMRc)h>nK!4l;KX)9IA(37#|Fa4w`+0p`z;Iq)bpIhGqUZHh!SEg& z({Z>`;iPva!&?~6?df20czJJSIG_K79pr3g^nCvFZAM?r?D-y}=XxJu_zxKUPZ|D0 zh96+^>0U+chl7ls%YT{S4>9`J7|!MA;QmQU*7};ra9&?-hV%NG#qb`;({_GY;Z$F< z8GaYTd42r@lf%pPFr(-5mPZ-=kC^cfcnA$aVGC6#{v5(=anf#wIyoup2G5isRzp8Mu z=g0V|UE|M;{wIw7BS!xX;N&MtS*OS?$st_J$z%A}8Gf0vOz&+Bf0*H~ zGMxKiX*P(EsJvWGwZg6Cy^hgyd%7LyZ*`#mngji}9q1onIJfh8hW`j<(DkxT-EV3w z*KG{v_4`wXS28&lpNbtMlJgLLTK;7Y_)>=dfYCQN-~$Zj>n-17IIqWlW;ieJH*p^< zC9;$2eTd<4*egUv28D7ogJjHO*MTzuYil5fY@yi_WFEIQPEL|ujP|2 zN~Cu&e#A%V8o7z$dVafF;Y7#Vdncp63VBUW=LnRve69D(5{}}Uo_tG*$x`YMJ>8Cj0^At{c zd0aJHa9!^`3MakXei{oXS?#}5!U8Ax+W)kMNlEL~^4+X{d0fq5@xbFsKL<>5cwAk{ zEb)M>%B{O?+DP5-#UX`jb=SV)ugz7lyY zht?7)S?RMREXq}ayrx&fi=b~{IK>Pll5-t?n!bZTB*Lrl)A%=#r$jjQIU4^Cfk;%0 zQv5Xj2!TjM&-FegP>DAouj#3;rbP7I5Bm96!mr0q)6Y=#NO(KL%Nfq)sOeHdxp+T0 zhsjxoJSCFfkDu17QmQS%tiRAR*r*U2{yj(P%Q6lFH4{?5hD>jkK2~|9}l2yJ} z!UCtUTkEAcAtj>!3Vs^zL7o!foc>;cN}SvIJj1_=yq1%}?BsIXjGp^J!Qyo_p`P}|Srnf}phqHefqv!Tt%W!VLpW$wmC;1B*p3Crq3@>2#6%6P0 z*E76?(O=1M9owWgz;K-<{Ac*-@^E~)-oe(b^3>N-U$4_tl_5MsgV<`lgpXl3Ki?e7 z@HUkv`b>uRG5jQk-^K884ByW1@eF^C;U_cvb%yJ6F@jDb#~_hCi$qTTqc4k5B0Njv zQIV0__VmSA455seaP^EhqeyRqseU#y+G5k4(Phj|O7=Aj#^?i3_=NSyo zAOMLrdQMCGWenG`O?WlK^<0SX8yS8U0V?$~T%SA8p+_06vV!AvhU;@@I&gBDI4tZW zl8D?jPG|V16-JwChN~qRakQJ^pJDVrWVoB*^xiW{q;rzU$$#mpF%UkP;ROu;EW>YP zxQF5N9y3ZL=RA><|Bf>Je1_Be$0!l~=R{8at7kYJ)9>Sga5_clY2zOJf7Y&eIh52~fMbw&4Drsa(>~GTk1cnSN z$jOD;ANI_{J$OE{i|ro-{{$s-xGP=16(Y`8AJafx+o4Y0z3!1bMtcp3>$A(i8W z5DW2~UBW9N%AI^YtTZL8K;7MsN6RRT?afk^7XR!()EgtmY&>J)qqIqceY^;(U+`#A z!izHUSJu_}1Ksp+lOJuqDUj%H+j1o(JFd)eeT1z{@t|9LDU)C-z(ZN_O!3{(@NG%E zS-wFc897DvPkfA8P<&kt+YCNo9Stipu5N5S7H?o&g^QQ2uttG4@d<4lNo<^%cF{0X zzx$%RvX0&{ux{kO-J#=(tHDu?HTGRgAeo98K|q}9 z|DM-w=uu5i0Ib1g@sD_h@+y2RtF>J`N9`5Q72*+D@kqbwW};IO$H!uA9<-K^+2Yw? zywRhz1?F_t1-*#6^75|5{;HXNdY%T|mMBw2j5{|(>rVBa~!-i#0zZhu3)mb&~q zzDgp#o?|6b?|iT=6CRu{?^?(@2t3Q$(%Rl!(-dtA-b(onh_bdT@PPFQN=E%+39G#5 zGvF!^3eY@@{a(D;CD<5TD>?(bE~hEb(INAyf52;V^uyr(&X&gOI|E+zG7wO=)ikzy z(ZAq%`dUApu*WmHs+kKJwdJy4G8jd7W$nCU&WsC_MQ@ziyGv+lK|*O zF!JNc(plnk3>`c;G4ZoLGi)6gNTrho-TEC`thRP|g-Hk*NxyyXGdlIoGDgzw(2uf#8Bn5cuL=(43~;tlzJ|H|%ee_NovqqPO^>jb*;_x z&JH6VA0rLq<12m_iB~bI{go}9`EBiZ*-3kFt?Fe0tNab^HF#TA{>t{&PQBzM7nDBX z|MRhk%hz|cm=cxIYu)!^e;$5nxi7kP;x`q)Udtx_`J>?1_XBW#l9{ajYS2>R_S5yU zWcgPK?%4ffWItWUN|ryU__=<%-jyu>jW+zgQSkTK@YD6nWc6>d;iv0D$@1%UQC@#^ zohVuUElR(>CPDtE>qg1)Z&Ume)Ry?mM!~;V@p1cWM!|p3hQDqU{I4i}UjF(~@E@_^ z4~&BUW5v(Q-!KaPOm%&S^HZBjw*Dq4eqMgM9-1t_$3}nKDEJF(_{&GZe~Ar$-zfM^ z8~zQW;9qRRzi|}&)i(U0QSdj}@ZUBHe*N809zUB#!QW@2e_#~+^le;9T>l-|Pd5Ja zbyCj1c@+FxZS>PUgvsjH*JJtkGdK$Voi_S+je`Gx;^+GJjDr85jsCr(;D5zN|GrW1 zziy*{|0wv6+UP$p3jX6Z`kxsEe|jp2k+}b##eTB!bF$*+@w;pk{1a{X={}BR^?Pji zpBn|gevb~f|L3FNzr;rWFGj&{+VImosL7Upu?;`XiIe58w&ADyM6CR7U=(U&@Z+gT z@i*|B5Uo2$e-eck~!jGqy+;UHsS0B^*_4Y?NV5k3(1HV=O z_rWjxZ#i)ER;f|@`CjbKz)#zw@gu-Uzt#T3Zh%PYHU+tZ|JrW7rTft-Z}s0%w`9@! z)yWpP=-Q6u)0_;6F?8uhoXDEy&~2 zAqW0D75@Wq)QRP%??I-3#_GRWlO^M+Bk+e-+GvKbcw8cSxrP8n8yLT_R=HX}6|DMvXpX1TOvph0KW#fr_#nV+Fu=C%k zieJZ>=CRs;CHP54iRHk?KFLv_7|DJwepdU#V7AkLfk!eF zreY-hwEkk%KL}7UpSWk_5fPvxsspXJ4=YxueWDmfHC>AkfbL&nbTW{HW&9 z<<|RWg5S>m?v0YdRD@)IHGUu$N!$M|03_4u|I;s&bWL&-{jc@w?SqQn>eoKS|C=bM z%vj66OYvLl@9NJ>`bidktDc?Uw=4hPM#-qlN#(D{59A_g{4J&5TK*oT{{ls?H=19U zzwspd`g>6E)0z)YR{QJ0Z)g8Y%KmP}O!lwDPwUtAzv7_3`Xb4wpZ`;062`w59rRa* zB!{UONq-}LR{eS7?92a>(yyP}S7H+Md%$m3{=1a^YQ;$USL0{Z-|3)#S-xZ(Nq?Jz z{^K_Kn{D(zq4Znh=S8KTKchev>A2C`8RPB!cTDkrtO;dt68u*LemnmyyG=4wD?ajH z8-7;*ZFSK9wig>NxtBP9I~n|T z1=t{BBhRUtozp&9C8W6~EQ~V^gKYBl+)(;J2$k z_a@2D{YTGwYyBF34E$NZaT*nua;M2%O|K8?eZ74|>(>NoJJUx0O*p3cwEo?y{MPZm zMCo^1Ce}S)Yfg;|D%Kb z+0!MV)}z_9e!c&D2m24$*uMcxnqSME?6UWNiPArk|7#V$)&Fft+E4ExwDW)VfGi>R zKMjdi`|owIe~Z$uPUEz@40kjqGcP&Ve;`Twf8}8RG8_A;O04#uh6YCQZ}s0HrC*m{ zo2~iveir!c{I^BvA5?@CzqjM3`E~tY>!3fE7JHFK(*H#V{nexlX;A!^?-bvRyjA~J z2mNhH>c7uHzxxiUnCt(FjsABX^lwj6|Jx4w583Fy(?)+@j(z>>2k9$iF{1yq|1{tM zzis_*mJ}~3LaP6-&31`X5eT^iD_e_CfzixNnEl?+*m7twl>YjNV73%(~Upcrm<>v(eBpWB(mqcckg(ZmHlha z=kwk@@B6*y+;i@)cjwJ}r)+1hYI};R1O6hv*Ob}>A;dr-?C<@5T(CX%82tE+!H~JC z3Qjkq!P~FSYEO$_qr-*7$5Y1^`~6n4wF%+rp&7cS31~?2hIcH%Af%L-Wr-Lg3WSDw z5?)TcNXIxuiqzAvbW7d9(j)bBEHk7&2+P4zAA)73)V)|{OMRFSy2x$+(6usY$TNrq zTfYvr-lz|@*@xwsk6V2^une4nq%=>s&3zId#OHJiwiO0j&r3BW*tQ`qc+Un`L-h^k z!x_%xOe_|;oXJaFsI2fhlh=5IEz{%teXMN3wpnq(){xH=Ebee_ZPcm#X+Br!Pf-(P zKl|~^mRx=l(+{@(Ti9&v%8B5vdntmq=w=1b+KIGOWlYg^t~-;b`Qn1R8ho=ut$#D? zB4qakTdverEdEnj%T?Ru571$0%h#H7>({82VO=fQHXT#_W?V4;onW}*zwKqtS3e3C zUvFH7dDVFQ&iopm7u9-Ci8H_6hxvs(vniz#=NlnU^^TA)7%INhSdLXjd7SyHe6vw& z@VK1$4Zhl7+gy(~*gDs@*7?RXPu`AczKv#l!Cg&0ua)aCo~xCAsP!`rs!aMz&X1XC z*PX7AFK(%GjKkMBytL(-mDa8XPp#@VtYP=5j=B6_w|aZkkUF=X#m=}<>U=mn*_k|< zl+8G@n_Z@cL%Z1;+R~PvYrz&AKI{a%2aBiqJkG5zqHUCSV` zmXXxruECALjz8G3izZ=bVJD#0M4i>-^P?JW@_0!vL0`AXS1}qIXlPbDOB8i)ljj1d zwWj*-q^^zX*2_1(?(Ge=URTLqF72g!t+`$w9BEDd4QavF&x6ffv@Yg9R9aIC?Wvyj z!#Q0s+Mf2Mc^}8N7Zpv^U1fW;-)iE|T8t1kwdd@=g)I}8v`@YF!C3g0855C#B2kt}vP_ocKq@sGbk9wJ3-e-hVMrofmV;zDgvyyV;iX{uNHRX@B0>0Q(?ZF! z3NaE(O(e>vNY{voLO{~^Vub=9=T1nN&K6)AyeBc@u|1*B2#_Zykn$tek%SsQ%O~ik@7GOUibSc z_`af$2I8?TB_cqK(FZ zwMJukL~BzTG(G5vxuTw8ZYfP)5f7X1H|!XNWxFM!y%5nph-g2;UB#@Y_r$}Qc?NEs z2Ol!*IKeG+N`jfUdX8Ba(VmECha%c>rRjf6fJ}@+J;%h}rQ*qsXq8G^COkJK-x3&k)q+7k>A6#i=%YosFO^R zc!Qi#ui?m%)GJH9$pJ~V?wD2u#2hlU?y0G8t!`4iUlfFQnZ^OrFkt!!6p>XC3|Tc4ZY>&+HWp8A%a$}OT(x}7lJ(OY z#lm@O9$npDw%n#U7p`xpTfB1N;%}{7xU_EhDo7rXYo7bpt{4;FxPHyrN0zT?SPBPM zykM_iHM_BW^2&e~`90uWQxXgA<-Ybs4KHfLg_v&jfxxAP2LXJ`<57g`g{` zE@N}#!ojsKoKS_Vi?KzLC7+|A8QC$6tzqnNIEE~ZlWKPt^E?nPBI{@D0cIP3{uv8mZpyKthN`5su0#8JC3oblnM$JemI2e-KZ(sJjSL%H?jf7PLV8m4uJM; zBb_!iW&2QsAo)8+I-P@5M%i*9lkML@>30m+`1g*)2P8_Sm9P$NXniZ2wT!KTL&(ly z?CXr31KsHH^j=5eIfl*!ZL zBsMXdB4|dN`OM}BV+-LJvL431&e$5b7&eloGWI_Pz{!1X82q@S&m4OcUt1&;WRF!*=Uh-!)MH80GgxNo6Ob^$D-Jw_}V6+V8_EnWO@E$89Nb@Ta0v` z|1!x^RD+=uSw1T3nQZ{pAp_q55mS?|LvXp%m^dQT#e~#G(AbXpUPG88> zBzT>%^-zUuGGnhZb_p~i%RT$$E@Q2fV^QpU$;$CWmS?nru{fUF`)0J0dBzuc4K+I)P_)}Ib_jhpMWLok@KO^YSK^ecm*IXVENF6<-^0x4C%7`3%5WZK zc|Y#vTJDxHvvtf}oC_aNC_0WOOFTNdK`x3eV^}}*7>l0LkJoiB>YDIoM%QD*Dz_S1 z3MkRRtYUZx@~ZwphVzk0rBBo-5;Le{2DAFXA7S`tR(~hMmoWVM z46moJBPycJbZkYTNO{9gGQ0#iRsSHvdHtjP;9U%l?7<~?tna=Pf%pZ6^RBzfaX8jy zggNVwA5)?`ynx~LER9JF=l%4L4CiUT!*J;*jKTKyo@E4gG*Ny{pn$leYKHUvThfCp4X?*NqOfEF>F2lNQTOVCbDfDVPz)aOL30R@}f;UNa% zDAZ0NUdnC`!})eHkKuefd6?mRXv< zAqx2^!AsRY&<}ov;p?eoWnljQBpt11jxsXf)_!+*LIz?e)DG{cx&7eV`@s+OgF6SA z?oI#eP*q`NTe#Ixe8dZx0mo-EoX@EJ46kPmyv%T3{{+MP>_N5ie*x+V?7v8)s~FBl zZWF`#$Q_j5)1rIy0>dLyuNoKcwL1}r|E(Wf%f#qVsDX$htRK&DsM}+N`AqgQme1ro ziPIa-hL;*3Kdaxs@CmH`28NePoP0N0_y7#5w|7P+eEOI>QGHvasPmv_zmcBLtfy=E zfI{pD$bP!-!Q=^(vwkFJL-#XAdMP3*(o>QpTOVi#`r68MVS1hdfhhJ7X-nB>Lmjf* z^ET#r8gyXHK15Wz*BP4+9S01p5SpJgv}w?TerB?oYgo-7WIx-NJ>4b1-kmX9Mnpd3uS1jGsKIWeyBM7yJyCI0gOks@^&%Zk9&u-sk~Iny zF?i+C1IkVvzBu9zKNUr4<7Rt^j1NG7LDTY%6N6gwnTwpjg;DZleD2BiOywq^1avLhi^vBBRko3(ha{9ICsZJ%AB;23`pOtG>-fp6vs-tj=Dfp~vs?xGZ zzHrATruJ(z0p`L#=uf1r)rOrD<^H7e@X=7UpLz z=o}U8V!m$nqx3M!isF79&YX_8*uz}V4j=8}lunt%`-WNd3SsrTUJbF|M?CNjq9Z}H z2bT>he`CZ;2ZO92?!rF~e-m-RgP?bHw2OUM8@qEOoeogSaYCHQ)L%l!7}`6u)=>)K z=m%c>cYgP;j8O|Lh==AyDB3SgY5bGFGey5S9G0HT)xSjZPWOoC?_f{+L$tla4!i%= z9b@jf=Kr@%=UjRwf*%`kc~%HjW*K*v>K6S@?q=yumQMUW+ z0>VjY`p7)FW?V6gG5P`Y2Xl;{szTMLDKP0Hm;P;Bm+!k1YNh>68x(w$sW)O+o$j== zG6?m@15N7@u<88Bv}#gOO5`Ua`W-qHj-MZy@XQ305U)7ki}T|XZq{0lJMHjAXXgI^ Da7XGv diff --git a/build/main b/build/main index b722624f61f12b783b6b2619b970ad1a239fc12d..32012b998aedb14571ae8cf8311a5deabe3bed8d 100755 GIT binary patch literal 55648 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 #include +#include "gnuplot-iostream.h" #include "HiddenLines.h" HL::HL() @@ -17,8 +18,8 @@ HL::HL() lines = construct_HWprob(); } -void print_sol(std::vector& lines) -{ +//Print the solution and convert the double::max and double::lowest to inf strings +void print_sol(std::vector& lines){ for(auto itr = lines.begin(); itr != lines.end(); itr++){ Line line = *itr; double start_range = line.get_vis_start(); @@ -104,6 +105,7 @@ std::vector HL::gen_sol(std::vector& ls){ } } +//Read from CSV file to construct this problem. Use std::set to order std::vector HL::construct_HWprob(){ //Set to hold all our Lines std::set sorted_lines; @@ -168,6 +170,7 @@ std::vector HL::construct_HWprob(){ return lines; } +//Merge the two halves and set visible start and end points std::vector merge(std::vector lh, std::vector rh){ std::vector merged; @@ -190,7 +193,6 @@ std::vector merge(std::vector lh, std::vector rh){ *ritr = l2; } merged.push_back(l1); - //merged.push_back(l2); litr++; } @@ -207,7 +209,6 @@ std::vector merge(std::vector lh, std::vector rh){ *litr = l1; merged.push_back(l2); } - litr++; ritr++; } @@ -243,6 +244,11 @@ std::vector HL::get_lines(){ return lines; } +/* +// Line merging process merges the two halves and keeps the order, but does not check for +// when intersection points fall to the left (more negative) of other intersection points. +// Need to remove the invisible lines caused by this case. +*/ std::vector remove_invis(std::vector &merged){ //Create separate visible line holder @@ -253,36 +259,37 @@ std::vector remove_invis(std::vector &merged){ merged.erase(merged.begin()); tmp_vis.push_back(merged.front()); merged.erase(merged.begin()); - int num_vis = 2; //Loop through the remainder of the original vector for(Line &line : merged){ //Pull out the back two lines - Line last = tmp_vis.at(num_vis -1); - Line seclast = tmp_vis.at(num_vis -2); + Line last = tmp_vis.at(tmp_vis.size()-1); + Line seclast = tmp_vis.at(tmp_vis.size()-2); //Intersection of our "known" visible lines vs the intersection of the 2nd to last vis line and the original vec double vis_isec = last.get_isec(seclast); double merg_isec = line.get_isec(seclast); while(merg_isec < vis_isec){ - //line intersects before the last line, and since line slope > last line slope, remove it - tmp_vis.erase(tmp_vis.begin() + (num_vis -1)); - num_vis--; + //Adjust visibility start and end points line.set_vis_start(merg_isec); + seclast.set_vis_end(merg_isec); + tmp_vis.at(tmp_vis.size()-2) = seclast; - if(num_vis == 1) + //line intersects before the last line, and since line slope > last line slope, remove it + tmp_vis.erase(tmp_vis.begin() + (tmp_vis.size()-1)); + + //We only have 1 line visible, no more comparisons needed to see if we have something out of order + if(tmp_vis.size() == 1) break; - last = tmp_vis.at(num_vis -1); - seclast = tmp_vis.at(num_vis -2); + //Otherwise, get our next lines to make sure we don't have something + last = tmp_vis.at(tmp_vis.size()-1); + seclast = tmp_vis.at(tmp_vis.size()-2); vis_isec = last.get_isec(seclast); merg_isec = line.get_isec(seclast); } - tmp_vis.push_back(line); - num_vis++; } - return tmp_vis; } diff --git a/src/Line.cpp b/src/Line.cpp index a85a089..b1a035c 100644 --- a/src/Line.cpp +++ b/src/Line.cpp @@ -1,8 +1,6 @@ //Line Class #include "Line.h" -#include - int Line::current_id = 0; @@ -11,8 +9,8 @@ Line::Line(double x, double y) set_slope(x); set_ycept(y); id = 0; - //set_vis_start(-std::numeric_limits::max()); - //set_vis_end(std::numeric_limits::max()); + + //Arbitrarily just say lines are visible starting at and ending at 0. set_vis_start(0); set_vis_end(0); } diff --git a/src/gnuplot-iostream.h b/src/gnuplot-iostream.h new file mode 100644 index 0000000..42be0fb --- /dev/null +++ b/src/gnuplot-iostream.h @@ -0,0 +1,2586 @@ +// vim:foldmethod=marker + +/* +Copyright (c) 2020 Daniel Stahlke (dan@stahlke.org) + +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. +*/ + +/* A C++ interface to gnuplot. + * Web page: http://www.stahlke.org/dan/gnuplot-iostream + * Documentation: https://github.com/dstahlke/gnuplot-iostream/wiki + * + * The whole library consists of this monolithic header file, for ease of installation (the + * Makefile and *.cc files are only for examples and tests). + * + * TODO: + * Callbacks via gnuplot's 'bind' function. This would allow triggering user functions when + * keys are pressed in the gnuplot window. However, it would require a PTY reader thread. + * Maybe temporary files read in a thread can replace PTY stuff. + */ + +#ifndef GNUPLOT_IOSTREAM_H +#define GNUPLOT_IOSTREAM_H + +// {{{1 Includes and defines + +#define GNUPLOT_IOSTREAM_VERSION 3 + +// C system includes +#include +#ifdef GNUPLOT_ENABLE_PTY +# include +# include +#ifdef __APPLE__ +# include +#else +# include +#endif +#endif // GNUPLOT_ENABLE_PTY + +// C++ system includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +// This is the version of boost which has v3 of the filesystem libraries by default. +#if BOOST_VERSION >= 104600 +# define GNUPLOT_USE_TMPFILE +# include +#endif // BOOST_VERSION + +// Note: this is here for reverse compatibility. The new way to enable blitz support is to +// just include the gnuplot-iostream.h header after you include the blitz header (likewise for +// armadillo). +#ifdef GNUPLOT_ENABLE_BLITZ +# include +#endif + +// If this is defined, warn about use of deprecated functions. +#ifdef GNUPLOT_DEPRECATE_WARN +# ifdef __GNUC__ +# define GNUPLOT_DEPRECATE(msg) __attribute__ ((deprecated(msg))) +# elif defined(_MSC_VER) +# define GNUPLOT_DEPRECATE(msg) __declspec(deprecated(msg)) +# else +# define GNUPLOT_DEPRECATE(msg) +# endif +#else +# define GNUPLOT_DEPRECATE(msg) +#endif + +// Patch for Windows by Damien Loison +#ifdef _WIN32 +# include +# define GNUPLOT_PCLOSE _pclose +# define GNUPLOT_POPEN _popen +# define GNUPLOT_FILENO _fileno +#else +# define GNUPLOT_PCLOSE pclose +# define GNUPLOT_POPEN popen +# define GNUPLOT_FILENO fileno +#endif + +#ifdef _WIN32 +# define GNUPLOT_ISNAN _isnan +#else +// cppreference.com says std::isnan is only for C++11. However, this seems to work on Linux +// and I am assuming that if isnan exists in math.h then std::isnan exists in cmath. +# define GNUPLOT_ISNAN std::isnan +#endif + +// MSVC gives a warning saying that fopen and getenv are not secure. But they are secure. +// Unfortunately their replacement functions are not simple drop-in replacements. The best +// solution is to just temporarily disable this warning whenever fopen or getenv is used. +// http://stackoverflow.com/a/4805353/1048959 +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define GNUPLOT_MSVC_WARNING_4996_PUSH \ + __pragma(warning(push)) \ + __pragma(warning(disable:4996)) +# define GNUPLOT_MSVC_WARNING_4996_POP \ + __pragma(warning(pop)) +#else +# define GNUPLOT_MSVC_WARNING_4996_PUSH +# define GNUPLOT_MSVC_WARNING_4996_POP +#endif + +#ifndef GNUPLOT_DEFAULT_COMMAND +#ifdef _WIN32 +// "pgnuplot" is considered deprecated according to the Internet. It may be faster. It +// doesn't seem to handle binary data though. +//# define GNUPLOT_DEFAULT_COMMAND "pgnuplot -persist" +// On Windows, gnuplot echos commands to stderr. So we forward its stderr to the bit bucket. +// Unfortunately, this means you will miss out on legitimate error messages. +# define GNUPLOT_DEFAULT_COMMAND "gnuplot -persist 2> NUL" +#else +# define GNUPLOT_DEFAULT_COMMAND "gnuplot -persist" +#endif +#endif + +// }}}1 + +namespace gnuplotio { + +// {{{1 Basic traits helpers +// +// The mechanisms constructed in this section enable us to detect what sort of datatype has +// been passed to a function. + +// This can be specialized as needed, in order to not use the STL interfaces for specific +// classes. +template +static constexpr bool dont_treat_as_stl_container = false; + + +template +static constexpr bool is_like_stl_container = false; + +template +static constexpr bool is_like_stl_container().begin()), + decltype(std::declval().end()), + typename T::value_type + >> = !dont_treat_as_stl_container; + +static_assert( is_like_stl_container>); +static_assert(!is_like_stl_container); + + +template +static constexpr bool is_like_stl_container2 = false; + +template +static constexpr bool is_like_stl_container2())), + decltype(end (std::declval())) + >> = !is_like_stl_container && !dont_treat_as_stl_container; + + +template +static constexpr bool is_boost_tuple_nulltype = + std::is_same_v; + +static_assert(is_boost_tuple_nulltype); + +template +static constexpr bool is_boost_tuple = false; + +template +static constexpr bool is_boost_tuple> = is_boost_tuple || is_boost_tuple_nulltype; + +static_assert( is_boost_tuple>); +static_assert( is_boost_tuple>); +static_assert(!is_boost_tuple>); +static_assert(!is_boost_tuple>); + +// }}}1 + +// {{{1 Tmpfile helper class +#ifdef GNUPLOT_USE_TMPFILE +// RAII temporary file. File is removed when this object goes out of scope. +class GnuplotTmpfile { +public: + explicit GnuplotTmpfile(bool _debug_messages) : + file(boost::filesystem::unique_path( + boost::filesystem::temp_directory_path() / + "tmp-gnuplot-%%%%-%%%%-%%%%-%%%%")), + debug_messages(_debug_messages) + { + if(debug_messages) { + std::cerr << "create tmpfile " << file << std::endl; + } + } + +private: + // noncopyable + GnuplotTmpfile(const GnuplotTmpfile &); + const GnuplotTmpfile& operator=(const GnuplotTmpfile &); + +public: + ~GnuplotTmpfile() { + if(debug_messages) { + std::cerr << "delete tmpfile " << file << std::endl; + } + // it is never good to throw exceptions from a destructor + try { + remove(file); + } catch(const std::exception &) { + std::cerr << "Failed to remove temporary file " << file << std::endl; + } + } + +public: + boost::filesystem::path file; + bool debug_messages; +}; + +class GnuplotTmpfileCollection { +public: + std::string make_tmpfile() { + const bool debug_messages = false; + std::shared_ptr tmp_file(new GnuplotTmpfile(debug_messages)); + // The file will be removed once the pointer is removed from the + // tmp_files container. + tmp_files.push_back(tmp_file); + return tmp_file->file.string(); + } + + void clear() { + tmp_files.clear(); + } + +private: + std::vector> tmp_files; +}; +#else // GNUPLOT_USE_TMPFILE +class GnuplotTmpfileCollection { +public: + std::string make_tmpfile() { + throw std::logic_error("no filename given and temporary files not enabled"); + } + + void clear() { } +}; +#endif // GNUPLOT_USE_TMPFILE +// }}}1 + +// {{{1 Feedback helper classes +// +// Used for reading stuff sent from gnuplot via gnuplot's "print" function. +// +// For example, this is used for capturing mouse clicks in the gnuplot window. There are two +// implementations, only the first of which is complete. The first implementation allocates a +// PTY (pseudo terminal) which is written to by gnuplot and read by us. This only works in +// Linux. The second implementation creates a temporary file which is written to by gnuplot +// and read by us. However, this doesn't currently work since fscanf doesn't block. It would +// be possible to get this working using a more complicated mechanism (select or threads) but I +// haven't had the need for it. + +class GnuplotFeedback { +public: + GnuplotFeedback() { } + virtual ~GnuplotFeedback() { } + virtual std::string filename() const = 0; + virtual FILE *handle() const = 0; + +private: + // noncopyable + GnuplotFeedback(const GnuplotFeedback &); + const GnuplotFeedback& operator=(const GnuplotFeedback &); +}; + +#ifdef GNUPLOT_ENABLE_PTY +#define GNUPLOT_ENABLE_FEEDBACK +class GnuplotFeedbackPty : public GnuplotFeedback { +public: + explicit GnuplotFeedbackPty(bool debug_messages) : + pty_fn(), + pty_fh(nullptr), + master_fd(-1), + slave_fd(-1) + { + // adapted from http://www.gnuplot.info/files/gpReadMouseTest.c + if(0 > openpty(&master_fd, &slave_fd, nullptr, nullptr, nullptr)) { + perror("openpty"); + throw std::runtime_error("openpty failed"); + } + char pty_fn_buf[1024]; + if(ttyname_r(slave_fd, pty_fn_buf, 1024)) { + perror("ttyname_r"); + throw std::runtime_error("ttyname failed"); + } + pty_fn = std::string(pty_fn_buf); + if(debug_messages) { + std::cerr << "feedback_fn=" << pty_fn << std::endl; + } + + // disable echo + struct termios tios; + if(tcgetattr(slave_fd, &tios) < 0) { + perror("tcgetattr"); + throw std::runtime_error("tcgetattr failed"); + } + tios.c_lflag &= ~(ECHO | ECHONL); + if(tcsetattr(slave_fd, TCSAFLUSH, &tios) < 0) { + perror("tcsetattr"); + throw std::runtime_error("tcsetattr failed"); + } + + pty_fh = fdopen(master_fd, "r"); + if(!pty_fh) { + throw std::runtime_error("fdopen failed"); + } + } + +private: + // noncopyable + GnuplotFeedbackPty(const GnuplotFeedbackPty &); + const GnuplotFeedbackPty& operator=(const GnuplotFeedbackPty &); + +public: + ~GnuplotFeedbackPty() { + if(pty_fh) fclose(pty_fh); + if(master_fd > 0) ::close(master_fd); + if(slave_fd > 0) ::close(slave_fd); + } + + std::string filename() const { + return pty_fn; + } + + FILE *handle() const { + return pty_fh; + } + +private: + std::string pty_fn; + FILE *pty_fh; + int master_fd, slave_fd; +}; +//#elif defined GNUPLOT_USE_TMPFILE +//// Currently this doesn't work since fscanf doesn't block (need something like "tail -f") +//#define GNUPLOT_ENABLE_FEEDBACK +//class GnuplotFeedbackTmpfile : public GnuplotFeedback { +//public: +// explicit GnuplotFeedbackTmpfile(bool debug_messages) : +// tmp_file(), +// fh(nullptr) +// { +// if(debug_messages) { +// std::cerr << "feedback_fn=" << filename() << std::endl; +// } +// GNUPLOT_MSVC_WARNING_4996_PUSH +// fh = std::fopen(filename().c_str(), "a"); +// GNUPLOT_MSVC_WARNING_4996_POP +// } +// +// ~GnuplotFeedbackTmpfile() { +// fclose(fh); +// } +// +//private: +// // noncopyable +// GnuplotFeedbackTmpfile(const GnuplotFeedbackTmpfile &); +// const GnuplotFeedbackTmpfile& operator=(const GnuplotFeedbackTmpfile &); +// +//public: +// std::string filename() const { +// return tmp_file.file.string(); +// } +// +// FILE *handle() const { +// return fh; +// } +// +//private: +// GnuplotTmpfile tmp_file; +// FILE *fh; +//}; +#endif // GNUPLOT_ENABLE_PTY, GNUPLOT_USE_TMPFILE +// }}}1 + +// {{{1 Traits and printers for entry datatypes +// +// This section contains the mechanisms for sending scalar and tuple data to gnuplot. Pairs +// and tuples are sent by appealing to the senders defined for their component scalar types. +// Senders for arrays are defined in a later section. +// +// There are three classes which need to be specialized for each supported datatype: +// 1. TextSender to send data as text. The default is to just send using the ostream's `<<` +// operator. +// 2. BinarySender to send data as binary, in a format which gnuplot can understand. There is +// no default implementation (unimplemented types raise a compile time error), however +// inheriting from FlatBinarySender will send the data literally as it is stored in memory. +// This suffices for most of the standard built-in types (e.g. uint32_t or double). +// 3. BinfmtSender sends a description of the data format to gnuplot (e.g. `%uint32`). Type +// `show datafile binary datasizes` in gnuplot to see a list of supported formats. + +// {{{2 Basic entry datatypes + +// Default TextSender, sends data using `<<` operator. +template +struct TextSender { + static void send(std::ostream &stream, const T &v) { + stream << v; + } +}; + +class BinarySenderNotImplemented : public std::logic_error { +public: + explicit BinarySenderNotImplemented(const std::string &w) : std::logic_error(w) { } +}; + +// Default BinarySender, raises a compile time error. +template +struct BinarySender { + static void send(std::ostream &, const T &) { + throw BinarySenderNotImplemented("BinarySender not implemented for this type"); + } +}; + +// This is a BinarySender implementation that just sends directly from memory. Data types +// which can be sent this way can have their BinarySender specialization inherit from this. +template +struct FlatBinarySender { + static void send(std::ostream &stream, const T &v) { + stream.write(reinterpret_cast(&v), sizeof(T)); + } +}; + +// Default BinfmtSender, raises a compile time error. +template +struct BinfmtSender { + static void send(std::ostream &) { + throw BinarySenderNotImplemented("BinfmtSender not implemented for this type"); + } +}; + +// BinfmtSender implementations for basic data types supported by gnuplot. +template<> struct BinfmtSender< float> { static void send(std::ostream &stream) { stream << "%float"; } }; +template<> struct BinfmtSender { static void send(std::ostream &stream) { stream << "%double"; } }; +template<> struct BinfmtSender< int8_t> { static void send(std::ostream &stream) { stream << "%int8"; } }; +template<> struct BinfmtSender< uint8_t> { static void send(std::ostream &stream) { stream << "%uint8"; } }; +template<> struct BinfmtSender< int16_t> { static void send(std::ostream &stream) { stream << "%int16"; } }; +template<> struct BinfmtSender { static void send(std::ostream &stream) { stream << "%uint16"; } }; +template<> struct BinfmtSender< int32_t> { static void send(std::ostream &stream) { stream << "%int32"; } }; +template<> struct BinfmtSender { static void send(std::ostream &stream) { stream << "%uint32"; } }; +template<> struct BinfmtSender< int64_t> { static void send(std::ostream &stream) { stream << "%int64"; } }; +template<> struct BinfmtSender { static void send(std::ostream &stream) { stream << "%uint64"; } }; + +// BinarySender implementations for basic data types supported by gnuplot. These types can +// just be sent as stored in memory, so all these senders inherit from FlatBinarySender. +template<> struct BinarySender< float> : public FlatBinarySender< float> { }; +template<> struct BinarySender : public FlatBinarySender { }; +template<> struct BinarySender< int8_t> : public FlatBinarySender< int8_t> { }; +template<> struct BinarySender< uint8_t> : public FlatBinarySender< uint8_t> { }; +template<> struct BinarySender< int16_t> : public FlatBinarySender< int16_t> { }; +template<> struct BinarySender : public FlatBinarySender { }; +template<> struct BinarySender< int32_t> : public FlatBinarySender< int32_t> { }; +template<> struct BinarySender : public FlatBinarySender { }; +template<> struct BinarySender< int64_t> : public FlatBinarySender< int64_t> { }; +template<> struct BinarySender : public FlatBinarySender { }; + +// Make char types print as integers, not as characters. +template +struct CastIntTextSender { + static void send(std::ostream &stream, const T &v) { + stream << static_cast(v); + } +}; +template<> struct TextSender< char> : public CastIntTextSender< char> { }; +template<> struct TextSender< signed char> : public CastIntTextSender< signed char> { }; +template<> struct TextSender< unsigned char> : public CastIntTextSender< unsigned char> { }; + +// Make sure that the same not-a-number string is printed on all platforms. +template +struct FloatTextSender { + static void send(std::ostream &stream, const T &v) { + if(GNUPLOT_ISNAN(v)) { stream << "nan"; } else { stream << v; } + } +}; +template<> struct TextSender< float> : FloatTextSender< float> { }; +template<> struct TextSender< double> : FloatTextSender< double> { }; +template<> struct TextSender : FloatTextSender { }; + +// }}}2 + +// {{{2 std::pair support + +template +struct TextSender> { + static void send(std::ostream &stream, const std::pair &v) { + TextSender::send(stream, v.first); + stream << " "; + TextSender::send(stream, v.second); + } +}; + +template +struct BinfmtSender> { + static void send(std::ostream &stream) { + BinfmtSender::send(stream); + BinfmtSender::send(stream); + } +}; + +template +struct BinarySender> { + static void send(std::ostream &stream, const std::pair &v) { + BinarySender::send(stream, v.first); + BinarySender::send(stream, v.second); + } +}; + +// }}}2 + +// {{{2 std::complex support + +template +struct TextSender> { + static void send(std::ostream &stream, const std::complex &v) { + TextSender::send(stream, v.real()); + stream << " "; + TextSender::send(stream, v.imag()); + } +}; + +template +struct BinfmtSender> { + static void send(std::ostream &stream) { + BinfmtSender::send(stream); + BinfmtSender::send(stream); + } +}; + +template +struct BinarySender> { + static void send(std::ostream &stream, const std::complex &v) { + BinarySender::send(stream, v.real()); + BinarySender::send(stream, v.imag()); + } +}; + +// }}}2 + +// {{{2 boost::tuple support + +template +struct TextSender> +> { + static void send(std::ostream &stream, const T &v) { + TextSender::send(stream, v.get_head()); + if constexpr (!is_boost_tuple_nulltype) { + stream << " "; + TextSender::send(stream, v.get_tail()); + } + } +}; + +template +struct BinfmtSender> +> { + static void send(std::ostream &stream) { + BinfmtSender::send(stream); + if constexpr (!is_boost_tuple_nulltype) { + stream << " "; + BinfmtSender::send(stream); + } + } +}; + +template +struct BinarySender> +> { + static void send(std::ostream &stream, const T &v) { + BinarySender::send(stream, v.get_head()); + if constexpr (!is_boost_tuple_nulltype) { + BinarySender::send(stream, v.get_tail()); + } + } +}; + +// }}}2 + +// {{{2 std::tuple support + +// http://stackoverflow.com/questions/6245735/pretty-print-stdtuple + +template struct int_{}; // compile-time counter + +template +void std_tuple_formatcode_helper(std::ostream &stream, const Tuple *, int_) { + std_tuple_formatcode_helper(stream, (const Tuple *)(0), int_()); + stream << " "; + BinfmtSender::type>::send(stream); +} + +template +void std_tuple_formatcode_helper(std::ostream &stream, const Tuple *, int_<0>) { + BinfmtSender::type>::send(stream); +} + +template +struct BinfmtSender> { + typedef typename std::tuple Tuple; + + static void send(std::ostream &stream) { + std_tuple_formatcode_helper(stream, (const Tuple *)(0), int_()); + } +}; + +template +void std_tuple_textsend_helper(std::ostream &stream, const Tuple &v, int_) { + std_tuple_textsend_helper(stream, v, int_()); + stream << " "; + TextSender::type>::send(stream, std::get(v)); +} + +template +void std_tuple_textsend_helper(std::ostream &stream, const Tuple &v, int_<0>) { + TextSender::type>::send(stream, std::get<0>(v)); +} + +template +struct TextSender> { + typedef typename std::tuple Tuple; + + static void send(std::ostream &stream, const Tuple &v) { + std_tuple_textsend_helper(stream, v, int_()); + } +}; + +template +void std_tuple_binsend_helper(std::ostream &stream, const Tuple &v, int_) { + std_tuple_binsend_helper(stream, v, int_()); + BinarySender::type>::send(stream, std::get(v)); +} + +template +void std_tuple_binsend_helper(std::ostream &stream, const Tuple &v, int_<0>) { + BinarySender::type>::send(stream, std::get<0>(v)); +} + +template +struct BinarySender> { + typedef typename std::tuple Tuple; + + static void send(std::ostream &stream, const Tuple &v) { + std_tuple_binsend_helper(stream, v, int_()); + } +}; + +// }}}2 + +// }}}1 + +// {{{1 ArrayTraits and Range classes +// +// This section handles sending of array data to gnuplot. It is rather complicated because of +// the diversity of storage schemes supported. For example, it treats a +// `std::pair, std::vector>` in the same way as a +// `std::vector>`, iterating through the two arrays in lockstep, and sending +// pairs to gnuplot as columns. In fact, any nested combination of pairs, tuples, STL +// containers, Blitz arrays, and Armadillo arrays is supported (with the caveat that, for +// instance, Blitz arrays should never be put into an STL container or you will suffer +// unpredictable results due the way Blitz handles assignment). Nested containers are +// considered to be multidimensional arrays. Although gnuplot only supports 1D and 2D arrays, +// our module is in principle not limited. +// +// The ArrayTraits class is specialized for every supported array or container type (the +// default, unspecialized, version of ArrayTraits exists only to tell you that something is +// *not* a container, via the is_container flag). ArrayTraits tells you the depth of a nested +// (or multidimensional) container, as well as the value type, and provides a specialized +// sort of iterator (a.k.a. "range"). Ranges are sort of like STL iterators, except that they +// have built-in knowledge of the end condition so you don't have to carry around both a +// begin() and an end() iterator like in STL. +// +// As an example of how this works, consider a std::pair of std::vectors. Ultimately this gets +// sent to gnuplot as two columns, so the two vectors need to be iterated in lockstep. +// The `value_type` of `std::pair, std::vector>` is then `std::pair` +// and this is what deferencing the range (iterator) gives. Internally, this range is built +// out of a pair of ranges (PairOfRange class), the `inc()` (advance to next element) +// method calls `inc()` on each of the children, and `deref()` calls `deref()` on each child +// and combines the results to return a `std::pair`. Tuples are handled as nested pairs. +// +// In addition to PairOfRange, there is also a VecOfRange class that can be used to treat the +// outermost part of a nested container as if it were a tuple. Since tuples are printed as +// columns, this is like treating a multidimensional array as if it were column-major. A +// VecOfRange is obtained by calling `get_columns_range`. This is used by, for instance, +// `send1d_colmajor`. The implementation is similar to that of PairOfRange. +// +// The range, accessed via `ArrayTraits::get_range`, will be of a different class depending +// on T, and this is defined by the ArrayTraits specialization for T. It will always have +// methods `inc()` to advance to the next element and `is_end()` for checking whether one has +// advanced past the final element. For nested containers, `deref_subiter()` returns a range +// iterator for the next nesting level. When at the innermost level of nesting, `deref()` +// returns the value of the entry the iterator points to (a scalar, pair, or tuple). +// Only one of `deref()` or `deref_subiter()` will be available, depending on whether there are +// deeper levels of nesting. The typedefs `value_type` and `subiter_type` tell the return +// types of these two methods. +// +// Support for standard C++ and boost containers and tuples of containers is provided in this +// section. Support for third party packages like Blitz and Armadillo is in a later section. + +// {{{2 ArrayTraits generic class and defaults + +// Error messages involving this stem from treating something that was not a container as if it +// was. This is only here to allow compiliation without errors in normal cases. +struct Error_WasNotContainer { + // This is just here to make VC++ happy. + // https://connect.microsoft.com/VisualStudio/feedback/details/777612/class-template-specialization-that-compiles-in-g-but-not-visual-c + typedef void subiter_type; +}; + +// The unspecialized version of this class gives traits for things that are *not* arrays. +template +class ArrayTraits { +public: + // The value type of elements after all levels of nested containers have been dereferenced. + typedef Error_WasNotContainer value_type; + // The type of the range (a.k.a. iterator) that `get_range()` returns. + typedef Error_WasNotContainer range_type; + // Tells whether T is in fact a container type. + static constexpr bool is_container = false; + // This flag supports the legacy behavior of automatically guessing whether the data should + // be treated as column major. This guessing happens when `send()` is called rather than + // `send1d()` or `send2d()`. This is deprecated, but is still supported for reverse + // compatibility. + static constexpr bool allow_auto_unwrap = false; + // The number of levels of nesting, or the dimension of multidimensional arrays. + static constexpr size_t depth = 0; + + // Returns the range (iterator) for an array. + static range_type get_range(const T &) { + static_assert((sizeof(T)==0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } +}; + +// Most specializations of ArrayTraits should inherit from this (with V set to the value type). +// It sets some default values. +template +class ArrayTraitsDefaults { +public: + typedef V value_type; + + static constexpr bool is_container = true; + static constexpr bool allow_auto_unwrap = true; + static constexpr size_t depth = ArrayTraits::depth + 1; +}; + +// This handles reference types, such as are given with std::tie. +// It also allows for instance "ArrayTraits" to match "ArrayTraits". +// I think this is okay to do... The alternative is to use remove_reference all over the place. +template +class ArrayTraits : public ArrayTraits { }; + +// This supports gp.send1d(std::forward_as_tuple(x, std::move(y))); +template +class ArrayTraits : public ArrayTraits { }; + +// }}}2 + +// {{{2 STL container support + +template +class IteratorRange { +public: + IteratorRange() { } + IteratorRange(const TI &_it, const TI &_end) : it(_it), end(_end) { } + + static constexpr bool is_container = ArrayTraits::is_container; + + // Error messages involving this stem from calling deref instead of deref_subiter for a nested + // container. + struct Error_InappropriateDeref { }; + using value_type = typename std::conditional_t; + + using subiter_type = typename ArrayTraits::range_type; + + bool is_end() const { return it == end; } + + void inc() { ++it; } + + value_type deref() const { + static_assert(sizeof(TV) && !is_container, + "deref called on nested container"); + if(is_end()) { + throw std::runtime_error("attepted to dereference past end of iterator"); + } + return *it; + } + + subiter_type deref_subiter() const { + static_assert(sizeof(TV) && is_container, + "deref_subiter called on non-nested container"); + if(is_end()) { + throw std::runtime_error("attepted to dereference past end of iterator"); + } + return ArrayTraits::get_range(*it); + } + +private: + TI it, end; +}; + +template +class ArrayTraits> +> : public ArrayTraitsDefaults { +public: + typedef IteratorRange range_type; + + static range_type get_range(const T &arg) { + return range_type(arg.begin(), arg.end()); + } +}; + +template +class ArrayTraits> +> : public ArrayTraitsDefaults()))>::value_type> { + using IterType = decltype(begin(std::declval())); + using ValType = typename std::iterator_traits::value_type; +public: + typedef IteratorRange range_type; + + static range_type get_range(const T &arg) { + return range_type(begin(arg), end(arg)); + } +}; + +// }}}2 + +// {{{2 C style array support + +template +class ArrayTraits : public ArrayTraitsDefaults { +public: + typedef IteratorRange range_type; + + static range_type get_range(const T (&arg)[N]) { + return range_type(arg, arg+N); + } +}; + +// }}}2 + +// {{{2 std::pair support + +template +class PairOfRange { + template + friend void deref_and_print(std::ostream &, const PairOfRange &, PrintMode); + +public: + PairOfRange() { } + PairOfRange(const RT &_l, const RU &_r) : l(_l), r(_r) { } + + static constexpr bool is_container = RT::is_container && RU::is_container; + + typedef std::pair value_type; + typedef PairOfRange subiter_type; + + bool is_end() const { + bool el = l.is_end(); + bool er = r.is_end(); + if(el != er) { + throw std::length_error("columns were different lengths"); + } + return el; + } + + void inc() { + l.inc(); + r.inc(); + } + + value_type deref() const { + return std::make_pair(l.deref(), r.deref()); + } + + subiter_type deref_subiter() const { + return subiter_type(l.deref_subiter(), r.deref_subiter()); + } + +private: + RT l; + RU r; +}; + +template +class ArrayTraits> { +public: + typedef PairOfRange::range_type, typename ArrayTraits::range_type> range_type; + typedef std::pair::value_type, typename ArrayTraits::value_type> value_type; + static constexpr bool is_container = ArrayTraits::is_container && ArrayTraits::is_container; + // Don't allow colwrap since it's already wrapped. + static constexpr bool allow_auto_unwrap = false; + // It is allowed for l_depth != r_depth, for example one column could be 'double' and the + // other column could be 'vector'. + static constexpr size_t l_depth = ArrayTraits::depth; + static constexpr size_t r_depth = ArrayTraits::depth; + static constexpr size_t depth = (l_depth < r_depth) ? l_depth : r_depth; + + static range_type get_range(const std::pair &arg) { + return range_type( + ArrayTraits::get_range(arg.first), + ArrayTraits::get_range(arg.second) + ); + } +}; + +// }}}2 + +// {{{2 boost::tuple support + +template +class ArrayTraits && !is_boost_tuple_nulltype + > +> : public ArrayTraits< + typename std::pair< + typename T::head_type, + typename T::tail_type + > +> { +public: + typedef typename T::head_type HT; + typedef typename T::tail_type TT; + + typedef ArrayTraits> parent; + + static typename parent::range_type get_range(const T &arg) { + return typename parent::range_type( + ArrayTraits::get_range(arg.get_head()), + ArrayTraits::get_range(arg.get_tail()) + ); + } +}; + +template +class ArrayTraits && is_boost_tuple_nulltype + > +> : public ArrayTraits< + typename T::head_type +> { + typedef typename T::head_type HT; + + typedef ArrayTraits parent; + +public: + static typename parent::range_type get_range(const T &arg) { + return parent::get_range(arg.get_head()); + } +}; + +// }}}2 + +// {{{2 std::tuple support + +template +struct StdTupUnwinder { + typedef std::pair< + typename StdTupUnwinder::type, + typename std::tuple_element::type + > type; + + static typename ArrayTraits::range_type get_range(const Tuple &arg) { + return typename ArrayTraits::range_type( + StdTupUnwinder::get_range(arg), + ArrayTraits::type>::get_range(std::get(arg)) + ); + } +}; + +template +struct StdTupUnwinder { + typedef typename std::tuple_element<0, Tuple>::type type; + + static typename ArrayTraits::range_type get_range(const Tuple &arg) { + return ArrayTraits::get_range(std::get<0>(arg)); + } +}; + +template +class ArrayTraits> : + public ArrayTraits, sizeof...(Args)-1>::type> +{ + typedef std::tuple Tuple; + typedef ArrayTraits::type> parent; + +public: + static typename parent::range_type get_range(const Tuple &arg) { + return StdTupUnwinder, sizeof...(Args)-1>::get_range(arg); + } +}; + +// }}}2 + +// {{{2 Support column unwrap of container (VecOfRange) +// +// VecOfRange (created via `get_columns_range()`) treats the outermost level of a nested +// container as if it were a tuple. Since tuples are sent to gnuplot as columns, this has the +// effect of addressing a multidimensional array in column major order. + +template +class VecOfRange { + template + friend void deref_and_print(std::ostream &, const VecOfRange &, PrintMode); + +public: + VecOfRange() { } + explicit VecOfRange(const std::vector &_rvec) : rvec(_rvec) { } + + static constexpr bool is_container = RT::is_container; + // Don't allow colwrap since it's already wrapped. + static constexpr bool allow_auto_unwrap = false; + + typedef std::vector value_type; + typedef VecOfRange subiter_type; + + bool is_end() const { + if(rvec.empty()) return true; + bool ret = rvec[0].is_end(); + for(size_t i=1; i subvec(rvec.size()); + for(size_t i=0; i rvec; +}; + +template +VecOfRange::range_type::subiter_type> +get_columns_range(const T &arg) { + typedef typename ArrayTraits::range_type::subiter_type U; + std::vector rvec; + typename ArrayTraits::range_type outer = ArrayTraits::get_range(arg); + while(!outer.is_end()) { + rvec.push_back(outer.deref_subiter()); + outer.inc(); + } + VecOfRange ret(rvec); + return ret; +} + +// }}}2 + +// }}}1 + +// {{{1 Array printing functions +// +// This section coordinates the sending of data to gnuplot. The ArrayTraits mechanism tells us +// about nested containers and provides iterators over them. Here we make use of this, +// deciding what dimensions should be treated as rows, columns, or blocks, telling gnuplot the +// size of the array if needed, and so on. + +// If this is set, then text-mode data will be sent in a format that is not compatible with +// gnuplot, but which helps the programmer tell what the library is thinking. Basically it +// puts brackets around groups of items and puts a message delineating blocks of data. +static bool debug_array_print = 0; + +// This is thrown when an empty container is being plotted. This exception should always +// be caught and should not propagate to the user. +class plotting_empty_container : public std::length_error { +public: + plotting_empty_container() : std::length_error("plotting empty container") { } +}; + +// {{{2 Tags (like enums for metaprogramming) + +// These tags define what our goal is, what sort of thing should ultimately be sent to the +// ostream. These tags are passed to the PrintMode template argument of the functions in this +// section. +// +// ModeText - Sends the data in an array in text format +// ModeBinary - Sends the data in an array in binary format +// ModeBinfmt - Sends the gnuplot format code for binary data (e.g. "%double%double") +// ModeSize - Sends the size of an array. Needed when sending binary data. +struct ModeText { static constexpr bool is_text = 1; static constexpr bool is_binfmt = 0; static constexpr bool is_size = 0; }; +struct ModeBinary { static constexpr bool is_text = 0; static constexpr bool is_binfmt = 0; static constexpr bool is_size = 0; }; +struct ModeBinfmt { static constexpr bool is_text = 0; static constexpr bool is_binfmt = 1; static constexpr bool is_size = 0; }; +struct ModeSize { static constexpr bool is_text = 0; static constexpr bool is_binfmt = 0; static constexpr bool is_size = 1; }; + +// Whether to treat the outermost level of a nested container as columns (column major mode). +struct ColUnwrapNo { }; +struct ColUnwrapYes { }; + +// The user must give a hint to describe how nested containers are to be interpreted. This is +// done by calling e.g. `send1d_colmajor()` or `send2d()`. This hint is then described by the +// following tags. This is passed to the OrganizationMode template argument. +struct Mode1D { static std::string class_name() { return "Mode1D" ; } }; +struct Mode2D { static std::string class_name() { return "Mode2D" ; } }; +struct Mode1DUnwrap { static std::string class_name() { return "Mode1DUnwrap"; } }; +struct Mode2DUnwrap { static std::string class_name() { return "Mode2DUnwrap"; } }; +// Support for the legacy behavior that guesses which of the above four modes should be used. +struct ModeAuto { static std::string class_name() { return "ModeAuto" ; } }; + +// }}}2 + +// {{{2 ModeAutoDecoder +// +// ModeAuto guesses which of Mode1D, Mode2D, Mode1DUnwrap, or Mode2DUnwrap should be used. +// This is provided for reverse compatibility; it is better to specify explicitly which mode to +// use. Since this is only for reverse compatibility, and shouldn't be used, I'm not going to +// spell out what the rules are. See below for details. + +template +struct ModeAutoDecoder { }; + +template +struct ModeAutoDecoder::depth == 1) + >> +{ + typedef Mode1D mode; +}; + +template +struct ModeAutoDecoder::depth == 2) && + !ArrayTraits::allow_auto_unwrap + >> +{ + typedef Mode2D mode; +}; + +template +struct ModeAutoDecoder::depth == 2) && + ArrayTraits::allow_auto_unwrap + >> +{ + typedef Mode1DUnwrap mode; +}; + +template +struct ModeAutoDecoder::depth > 2) && + ArrayTraits::allow_auto_unwrap + >> +{ + typedef Mode2DUnwrap mode; +}; + +template +struct ModeAutoDecoder::depth > 2) && + !ArrayTraits::allow_auto_unwrap + >> +{ + typedef Mode2D mode; +}; + +// }}}2 + +// The data is processed using several levels of functions that call each other in sequence, +// each defined in a subsection of code below. Because C++ wants you to declare a function +// before using it, we begin with the innermost function. So in order to see the sequence in +// which these are called, you should read the following subsections in reverse order. Nested +// arrays are formated into blocks (for 2D data) and lines (for 1D or 2D data), then further +// nesting levels are formatted into columns. Also tag dispatching is used in order to define +// various sorts of behavior. Each of these tasks is handled by one of the following +// subsections. + +// {{{2 send_scalar() +// +// Send a scalar in one of three possible ways: via TextSender, BinarySender, or BinfmtSender, +// depending on which PrintMode tag is passed to the function. + +template +void send_scalar(std::ostream &stream, const T &arg, ModeText) { + TextSender::send(stream, arg); +} + +template +void send_scalar(std::ostream &stream, const T &arg, ModeBinary) { + BinarySender::send(stream, arg); +} + +template +void send_scalar(std::ostream &stream, const T &, ModeBinfmt) { + BinfmtSender::send(stream); +} + +// }}}2 + +// {{{2 deref_and_print() +// +// Dereferences and prints the given range (iterator). At this point we are done with treating +// containers as blocks (for 2D data) and lines (for 1D or 2D data). Any further levels of +// nested containers will at this point be treated as columns. + +// If arg is not a container, then print it via send_scalar(). +template +typename std::enable_if_t +deref_and_print(std::ostream &stream, const T &arg, PrintMode) { + const typename T::value_type &v = arg.deref(); + send_scalar(stream, v, PrintMode()); +} + +// If arg is a container (but not a PairOfRange or VecOfRange, which are handled below) then +// treat the contents as columns, iterating over the contents recursively. If outputting in +// text mode, put a space between columns. +template +typename std::enable_if_t +deref_and_print(std::ostream &stream, const T &arg, PrintMode) { + if(arg.is_end()) throw plotting_empty_container(); + typename T::subiter_type subrange = arg.deref_subiter(); + if(PrintMode::is_binfmt && subrange.is_end()) throw plotting_empty_container(); + if(debug_array_print && PrintMode::is_text) stream << "{"; + bool first = true; + while(!subrange.is_end()) { + if(!first && PrintMode::is_text) stream << " "; + first = false; + deref_and_print(stream, subrange, PrintMode()); + subrange.inc(); + } + if(debug_array_print && PrintMode::is_text) stream << "}"; +} + +// PairOfRange is treated as columns. In text mode, put a space between columns. +template +void deref_and_print(std::ostream &stream, const PairOfRange &arg, PrintMode) { + deref_and_print(stream, arg.l, PrintMode()); + if(PrintMode::is_text) stream << " "; + deref_and_print(stream, arg.r, PrintMode()); +} + +// VecOfRange is treated as columns. In text mode, put a space between columns. +template +void deref_and_print(std::ostream &stream, const VecOfRange &arg, PrintMode) { + if(PrintMode::is_binfmt && arg.rvec.empty()) throw plotting_empty_container(); + for(size_t i=0; i +typename std::enable_if_t<(Depth==1) && !PrintMode::is_size> +print_block(std::ostream &stream, T &arg, PrintMode) { + if(PrintMode::is_binfmt && arg.is_end()) throw plotting_empty_container(); + for(; !arg.is_end(); arg.inc()) { + //print_entry(arg.deref()); + deref_and_print(stream, arg, PrintMode()); + // If asked to print the binary format string, only the first element needs to be + // looked at. + if(PrintMode::is_binfmt) break; + if(PrintMode::is_text) stream << std::endl; + } +} + +// Depth>1 and we are not asked to print the size of the array. Loop over the range and +// recurse into print_block() with Depth -> Depth-1. +template +typename std::enable_if_t<(Depth>1) && !PrintMode::is_size> +print_block(std::ostream &stream, T &arg, PrintMode) { + if(PrintMode::is_binfmt && arg.is_end()) throw plotting_empty_container(); + bool first = true; + for(; !arg.is_end(); arg.inc()) { + if(first) { + first = false; + } else { + if(PrintMode::is_text) stream << std::endl; + } + if(debug_array_print && PrintMode::is_text) stream << "" << std::endl; + if(arg.is_end()) throw plotting_empty_container(); + typename T::subiter_type sub = arg.deref_subiter(); + print_block(stream, sub, PrintMode()); + // If asked to print the binary format string, only the first element needs to be + // looked at. + if(PrintMode::is_binfmt) break; + } +} + +// Determine how many elements are in the given range. Used in the functions below. +template +size_t get_range_size(const T &arg) { + // FIXME - not the fastest way. Implement a size() method for range. + size_t ret = 0; + for(T i=arg; !i.is_end(); i.inc()) ++ret; + return ret; +} + +// Depth==1 and we are asked to print the size of the array. +template +typename std::enable_if_t<(Depth==1) && PrintMode::is_size> +print_block(std::ostream &stream, T &arg, PrintMode) { + stream << get_range_size(arg); +} + +// Depth>1 and we are asked to print the size of the array. +template +typename std::enable_if_t<(Depth>1) && PrintMode::is_size> +print_block(std::ostream &stream, T &arg, PrintMode) { + if(arg.is_end()) throw plotting_empty_container(); + // It seems that size for two dimensional arrays needs the fastest varying index first, + // contrary to intuition. The gnuplot documentation is not too clear on this point. + typename T::subiter_type sub = arg.deref_subiter(); + print_block(stream, sub, PrintMode()); + stream << "," << get_range_size(arg); +} + +// }}}2 + +// {{{2 handle_colunwrap_tag() +// +// If passed the ColUnwrapYes then treat the outermost nested container as columns by calling +// get_columns_range(). Otherwise just call get_range(). The range iterator is then passed to +// print_block() for further processing. + +template +void handle_colunwrap_tag(std::ostream &stream, const T &arg, ColUnwrapNo, PrintMode) { + static_assert(ArrayTraits::depth >= Depth, "container not deep enough"); + typename ArrayTraits::range_type range = ArrayTraits::get_range(arg); + print_block(stream, range, PrintMode()); +} + +template +void handle_colunwrap_tag(std::ostream &stream, const T &arg, ColUnwrapYes, PrintMode) { + static_assert(ArrayTraits::depth >= Depth+1, "container not deep enough"); + VecOfRange::range_type::subiter_type> cols = get_columns_range(arg); + print_block(stream, cols, PrintMode()); +} + +// }}}2 + +// {{{2 handle_organization_tag() +// +// Parse the OrganizationMode tag then forward to handle_colunwrap_tag() for further +// processing. If passed the Mode1D or Mode2D tags, then set Depth=1 or Depth=2. If passed +// Mode{1,2}DUnwrap then use the ColUnwrapYes tag. If passed ModeAuto (which is for legacy +// support) then use ModeAutoDecoder to guess which of Mode1D, Mode2D, etc. should be used. + +template +void handle_organization_tag(std::ostream &stream, const T &arg, Mode1D, PrintMode) { + handle_colunwrap_tag<1>(stream, arg, ColUnwrapNo(), PrintMode()); +} + +template +void handle_organization_tag(std::ostream &stream, const T &arg, Mode2D, PrintMode) { + handle_colunwrap_tag<2>(stream, arg, ColUnwrapNo(), PrintMode()); +} + +template +void handle_organization_tag(std::ostream &stream, const T &arg, Mode1DUnwrap, PrintMode) { + handle_colunwrap_tag<1>(stream, arg, ColUnwrapYes(), PrintMode()); +} + +template +void handle_organization_tag(std::ostream &stream, const T &arg, Mode2DUnwrap, PrintMode) { + handle_colunwrap_tag<2>(stream, arg, ColUnwrapYes(), PrintMode()); +} + +template +void handle_organization_tag(std::ostream &stream, const T &arg, ModeAuto, PrintMode) { + handle_organization_tag(stream, arg, typename ModeAutoDecoder::mode(), PrintMode()); +} + +// }}}2 + +// The entry point for the processing defined in this section. It just forwards immediately to +// handle_organization_tag(). This function is only here to give a sane name to the entry +// point. +// +// The allowed values for the OrganizationMode and PrintMode tags are defined in the beginning +// of this section. +template +void top_level_array_sender(std::ostream &stream, const T &arg, OrganizationMode, PrintMode) { + handle_organization_tag(stream, arg, OrganizationMode(), PrintMode()); +} + +// }}}1 + +// {{{1 PlotGroup + +class PlotData { +public: + PlotData() { } + + template + PlotData( + const T &arg, + const std::string &_plotspec, + const std::string &_arr_or_rec, + OrganizationMode, PrintMode + ) : + plotspec(_plotspec), + is_text(PrintMode::is_text), + is_inline(true), + has_data(true), + arr_or_rec(_arr_or_rec) + { + { + std::ostringstream tmp; + top_level_array_sender(tmp, arg, OrganizationMode(), PrintMode()); + data = tmp.str(); + } + + if(!is_text) { + try { + { + std::ostringstream tmp; + top_level_array_sender(tmp, arg, OrganizationMode(), ModeBinfmt()); + bin_fmt = tmp.str(); + } + { + std::ostringstream tmp; + top_level_array_sender(tmp, arg, OrganizationMode(), ModeSize()); + bin_size = tmp.str(); + } + } catch(const plotting_empty_container &) { + bin_fmt = ""; + bin_size = "0"; + } + } + } + + explicit PlotData(const std::string &_plotspec) : + plotspec(_plotspec), + is_text(true), + is_inline(false), + has_data(false) + { } + + PlotData &file(const std::string &fn) { + filename = fn; + is_inline = false; + + std::ios_base::openmode mode = std::fstream::out; + if(!is_text) mode |= std::fstream::binary; + std::fstream fh(filename.c_str(), mode); + fh << data; + fh.close(); + + return *this; + } + + std::string plotCmd() const { + std::string cmd; + if(has_data) { + if(filename.empty()) { + cmd += "'-' "; + } else { + // FIXME - hopefully filename doesn't contain quotes or such... + cmd += "'" + filename + "' "; + } + if(!is_text) { + cmd += binConfig() + " "; + } + } + cmd += plotspec; + return cmd; + } + + bool isInline() const { + return is_inline; + } + + const std::string &getData() const { + return data; + } + + bool isText() const { return is_text; } + + bool isBinary() const { return !is_text; } + +private: + std::string binConfig() const { + return "binary format='" + bin_fmt + "' " + arr_or_rec + "=(" + bin_size + ")"; + } + +private: + std::string plotspec; + bool is_text; + bool is_inline; + bool has_data; + std::string data; + std::string filename; + std::string arr_or_rec; + std::string bin_fmt; + std::string bin_size; +}; + +class PlotGroup { +public: + friend class Gnuplot; + + explicit PlotGroup(const std::string &plot_type_) : plot_type(plot_type_) { } + + PlotGroup &add_preamble(const std::string &s) { + preamble_lines.push_back(s); + return *this; + } + + PlotGroup &add_plot(const std::string &plotspec) { plots.emplace_back(plotspec); return *this; } + + template PlotGroup &add_plot1d (const T &arg, const std::string &plotspec="", const std::string &text_array_record="text") { add(arg, plotspec, text_array_record, Mode1D ()); return *this; } + template PlotGroup &add_plot2d (const T &arg, const std::string &plotspec="", const std::string &text_array_record="text") { add(arg, plotspec, text_array_record, Mode2D ()); return *this; } + template PlotGroup &add_plot1d_colmajor(const T &arg, const std::string &plotspec="", const std::string &text_array_record="text") { add(arg, plotspec, text_array_record, Mode1DUnwrap()); return *this; } + template PlotGroup &add_plot2d_colmajor(const T &arg, const std::string &plotspec="", const std::string &text_array_record="text") { add(arg, plotspec, text_array_record, Mode2DUnwrap()); return *this; } + + PlotGroup &file(const std::string &fn) { + assert(!plots.empty()); + plots.back().file(fn); + return *this; + } + + size_t num_plots() const { return plots.size(); } + +private: + template + void add(const T &arg, const std::string &plotspec, const std::string &text_array_record, OrganizationMode) { + if(!( + text_array_record == "text" || + text_array_record == "array" || + text_array_record == "record" + )) throw std::logic_error("text_array_record must be one of text, array, or record (was "+ + text_array_record+")"); + + if(text_array_record == "text") { + plots.emplace_back(arg, plotspec, + "array", // arbitrary value + OrganizationMode(), ModeText()); + } else { + plots.emplace_back(arg, plotspec, text_array_record, + OrganizationMode(), ModeBinary()); + } + } + + std::string plot_type; + std::vector preamble_lines; + std::vector plots; +}; + +// }}}1 + +// {{{1 FileHandleWrapper + +// This holds the file handle that gnuplot commands will be sent to. The purpose of this +// wrapper is twofold: +// 1. It allows storing the FILE* before it gets passed to the boost::iostreams::stream +// constructor (which is a base class of the main Gnuplot class). This is accomplished +// via multiple inheritance as described at http://stackoverflow.com/a/3821756/1048959 +// 2. It remembers whether the handle needs to be closed via fclose or pclose. +struct FileHandleWrapper { + FileHandleWrapper(std::FILE *_fh, bool _should_use_pclose) : + wrapped_fh(_fh), should_use_pclose(_should_use_pclose) { } + + void fh_close() { + if(should_use_pclose) { + if(GNUPLOT_PCLOSE(wrapped_fh)) { + std::cerr << "pclose returned error: " << strerror(errno) << std::endl; + } + } else { + if(fclose(wrapped_fh)) { + std::cerr << "fclose returned error" << std::endl; + } + } + } + + int fh_fileno() { + return GNUPLOT_FILENO(wrapped_fh); + } + + std::FILE *wrapped_fh; + bool should_use_pclose; +}; + +// }}}1 + +// {{{1 Main class + +class Gnuplot : + // Some setup needs to be done before obtaining the file descriptor that gets passed to + // boost::iostreams::stream. This is accomplished by using a multiple inheritance trick, + // as described at http://stackoverflow.com/a/3821756/1048959 + private FileHandleWrapper, + public boost::iostreams::stream +{ +private: + static std::string get_default_cmd() { + GNUPLOT_MSVC_WARNING_4996_PUSH + char *from_env = std::getenv("GNUPLOT_IOSTREAM_CMD"); + GNUPLOT_MSVC_WARNING_4996_POP + if(from_env && from_env[0]) { + return from_env; + } else { + return GNUPLOT_DEFAULT_COMMAND; + } + } + + static FileHandleWrapper open_cmdline(const std::string &in) { + std::string cmd = in.empty() ? get_default_cmd() : in; + assert(!cmd.empty()); + if(cmd[0] == '>') { + std::string fn = cmd.substr(1); + GNUPLOT_MSVC_WARNING_4996_PUSH + FILE *fh = std::fopen(fn.c_str(), "w"); + GNUPLOT_MSVC_WARNING_4996_POP + if(!fh) throw std::ios_base::failure("cannot open file "+fn); + return FileHandleWrapper(fh, false); + } else { + FILE *fh = GNUPLOT_POPEN(cmd.c_str(), "w"); + if(!fh) throw std::ios_base::failure("cannot open pipe "+cmd); + return FileHandleWrapper(fh, true); + } + } + +public: + explicit Gnuplot(const std::string &_cmd="") : + FileHandleWrapper(open_cmdline(_cmd)), + boost::iostreams::stream( + fh_fileno(), +#if BOOST_VERSION >= 104400 + boost::iostreams::never_close_handle +#else + false +#endif + ), + feedback(nullptr), + tmp_files(new GnuplotTmpfileCollection()), + debug_messages(false), + transport_tmpfile(false) + { + set_stream_options(*this); + } + + explicit Gnuplot(FILE *_fh) : + FileHandleWrapper(_fh, 0), + boost::iostreams::stream( + fh_fileno(), +#if BOOST_VERSION >= 104400 + boost::iostreams::never_close_handle +#else + false +#endif + ), + feedback(nullptr), + tmp_files(new GnuplotTmpfileCollection()), + debug_messages(false), + transport_tmpfile(false) + { + set_stream_options(*this); + } + +private: + // noncopyable + Gnuplot(const Gnuplot &) = delete; + const Gnuplot& operator=(const Gnuplot &) = delete; + +public: + ~Gnuplot() { + if(debug_messages) { + std::cerr << "ending gnuplot session" << std::endl; + } + + // FIXME - boost's close method calls close() on the file descriptor, but we need to + // use sometimes use pclose instead. For now, just skip calling boost's close and use + // flush just in case. + do_flush(); + // Wish boost had a pclose method... + //close(); + + fh_close(); + + delete feedback; + } + + void useTmpFile(bool state) { + transport_tmpfile = state; + } + + void clearTmpfiles() { + // destructors will cause deletion + tmp_files->clear(); + } + +public: + void do_flush() { + *this << std::flush; + fflush(wrapped_fh); + } + +private: + std::string make_tmpfile() { + return tmp_files->make_tmpfile(); + } + + void set_stream_options(std::ostream &os) const + { + os << std::defaultfloat << std::setprecision(17); // refer + } + +public: +// {{{2 Generic sender routines. +// +// These are declared public, but are undocumented. It is recommended to use the functions in +// the next section, which serve as adapters that pass specific values for the OrganizationMode +// tag. + + template + Gnuplot &send(const T &arg, OrganizationMode) { + top_level_array_sender(*this, arg, OrganizationMode(), ModeText()); + *this << "e" << std::endl; // gnuplot's "end of array" token + do_flush(); // probably not really needed, but doesn't hurt + return *this; + } + + template + Gnuplot &sendBinary(const T &arg, OrganizationMode) { + top_level_array_sender(*this, arg, OrganizationMode(), ModeBinary()); + do_flush(); // probably not really needed, but doesn't hurt + return *this; + } + + template + std::string binfmt(const T &arg, const std::string &arr_or_rec, OrganizationMode) { + assert((arr_or_rec == "array") || (arr_or_rec == "record")); + std::string ret; + try { + std::ostringstream tmp; + tmp << " format='"; + top_level_array_sender(tmp, arg, OrganizationMode(), ModeBinfmt()); + tmp << "' " << arr_or_rec << "=("; + top_level_array_sender(tmp, arg, OrganizationMode(), ModeSize()); + tmp << ")"; + tmp << " "; + ret = tmp.str(); + } catch(const plotting_empty_container &) { + ret = std::string(" format='' ") + arr_or_rec + "=(0) "; + } + return ret; + } + + // NOTE: empty filename makes temporary file + template + std::string file(const T &arg, std::string filename, OrganizationMode) { + if(filename.empty()) filename = make_tmpfile(); + std::fstream tmp_stream(filename.c_str(), std::fstream::out); + tmp_stream.copyfmt(*this); + top_level_array_sender(tmp_stream, arg, OrganizationMode(), ModeText()); + tmp_stream.close(); + + std::ostringstream cmdline; + // FIXME - hopefully filename doesn't contain quotes or such... + cmdline << " '" << filename << "' "; + return cmdline.str(); + } + + // NOTE: empty filename makes temporary file + template + std::string binaryFile(const T &arg, std::string filename, const std::string &arr_or_rec, OrganizationMode) { + if(filename.empty()) filename = make_tmpfile(); + std::fstream tmp_stream(filename.c_str(), std::fstream::out | std::fstream::binary); + top_level_array_sender(tmp_stream, arg, OrganizationMode(), ModeBinary()); + tmp_stream.close(); + + std::ostringstream cmdline; + // FIXME - hopefully filename doesn't contain quotes or such... + cmdline << " '" << filename << "' binary" << binfmt(arg, arr_or_rec, OrganizationMode()); + return cmdline.str(); + } + +// }}}2 + +// {{{2 Deprecated data sending interface that guesses an appropriate OrganizationMode. This is here +// for reverse compatibility. Don't use it. A warning will be printed if +// GNUPLOT_DEPRECATE_WARN is defined. + + template Gnuplot GNUPLOT_DEPRECATE("use send1d or send2d") + &send(const T &arg) { return send(arg, ModeAuto()); } + + template std::string GNUPLOT_DEPRECATE("use binfmt1d or binfmt2d") + binfmt(const T &arg, const std::string &arr_or_rec="array") + { return binfmt(arg, arr_or_rec, ModeAuto()); } + + template Gnuplot GNUPLOT_DEPRECATE("use sendBinary1d or sendBinary2d") + &sendBinary(const T &arg) { return sendBinary(arg, ModeAuto()); } + + template std::string GNUPLOT_DEPRECATE("use file1d or file2d") + file(const T &arg, const std::string &filename="") + { return file(arg, filename, ModeAuto()); } + + template std::string GNUPLOT_DEPRECATE("use binArr1d or binArr2d") + binaryFile(const T &arg, const std::string &filename="", const std::string &arr_or_rec="array") + { return binaryFile(arg, filename, arr_or_rec, ModeAuto()); } + +// }}}2 + +// {{{2 Public (documented) data sending interface. +// +// It seems odd to define 16 different functions, but I think this ends up being the most +// convenient in terms of usage by the end user. + + template Gnuplot &send1d (const T &arg) { return send(arg, Mode1D ()); } + template Gnuplot &send2d (const T &arg) { return send(arg, Mode2D ()); } + template Gnuplot &send1d_colmajor(const T &arg) { return send(arg, Mode1DUnwrap()); } + template Gnuplot &send2d_colmajor(const T &arg) { return send(arg, Mode2DUnwrap()); } + + template Gnuplot &sendBinary1d (const T &arg) { return sendBinary(arg, Mode1D ()); } + template Gnuplot &sendBinary2d (const T &arg) { return sendBinary(arg, Mode2D ()); } + template Gnuplot &sendBinary1d_colmajor(const T &arg) { return sendBinary(arg, Mode1DUnwrap()); } + template Gnuplot &sendBinary2d_colmajor(const T &arg) { return sendBinary(arg, Mode2DUnwrap()); } + + template std::string file1d (const T &arg, const std::string &filename="") { return file(arg, filename, Mode1D ()); } + template std::string file2d (const T &arg, const std::string &filename="") { return file(arg, filename, Mode2D ()); } + template std::string file1d_colmajor(const T &arg, const std::string &filename="") { return file(arg, filename, Mode1DUnwrap()); } + template std::string file2d_colmajor(const T &arg, const std::string &filename="") { return file(arg, filename, Mode2DUnwrap()); } + + template std::string binFmt1d (const T &arg, const std::string &arr_or_rec) { return binfmt(arg, arr_or_rec, Mode1D ()); } + template std::string binFmt2d (const T &arg, const std::string &arr_or_rec) { return binfmt(arg, arr_or_rec, Mode2D ()); } + template std::string binFmt1d_colmajor(const T &arg, const std::string &arr_or_rec) { return binfmt(arg, arr_or_rec, Mode1DUnwrap()); } + template std::string binFmt2d_colmajor(const T &arg, const std::string &arr_or_rec) { return binfmt(arg, arr_or_rec, Mode2DUnwrap()); } + + template std::string binFile1d (const T &arg, const std::string &arr_or_rec, const std::string &filename="") { return binaryFile(arg, filename, arr_or_rec, Mode1D ()); } + template std::string binFile2d (const T &arg, const std::string &arr_or_rec, const std::string &filename="") { return binaryFile(arg, filename, arr_or_rec, Mode2D ()); } + template std::string binFile1d_colmajor(const T &arg, const std::string &arr_or_rec, const std::string &filename="") { return binaryFile(arg, filename, arr_or_rec, Mode1DUnwrap()); } + template std::string binFile2d_colmajor(const T &arg, const std::string &arr_or_rec, const std::string &filename="") { return binaryFile(arg, filename, arr_or_rec, Mode2DUnwrap()); } + +// }}}2 + +#ifdef GNUPLOT_ENABLE_FEEDBACK +public: + // Input variables are set to the mouse position and button. If the gnuplot + // window is closed, button -1 is returned. The msg parameter is the prompt + // that is printed to the console. + void getMouse( + double &mx, double &my, int &mb, + std::string msg="Click Mouse!" + ) { + allocFeedback(); + + *this << "set mouse" << std::endl; + *this << "pause mouse \"" << msg << "\\n\"" << std::endl; + *this << "if (exists(\"MOUSE_X\")) print MOUSE_X, MOUSE_Y, MOUSE_BUTTON; else print 0, 0, -1;" << std::endl; + if(debug_messages) { + std::cerr << "begin scanf" << std::endl; + } + if(3 != fscanf(feedback->handle(), "%50lf %50lf %50d", &mx, &my, &mb)) { + throw std::runtime_error("could not parse reply"); + } + if(debug_messages) { + std::cerr << "end scanf" << std::endl; + } + } + +private: + void allocFeedback() { + if(!feedback) { +#ifdef GNUPLOT_ENABLE_PTY + feedback = new GnuplotFeedbackPty(debug_messages); +//#elif defined GNUPLOT_USE_TMPFILE +//// Currently this doesn't work since fscanf doesn't block (need something like "tail -f") +// feedback = new GnuplotFeedbackTmpfile(debug_messages); +#else + // This shouldn't happen because we are in an `#ifdef GNUPLOT_ENABLE_FEEDBACK` + // block which should only be activated if GNUPLOT_ENABLE_PTY is defined. + static_assert((sizeof(T) == 0), "No feedback mechanism defined."); +#endif + *this << "set print \"" << feedback->filename() << "\"" << std::endl; + } + } +#endif // GNUPLOT_ENABLE_FEEDBACK + +// {{{2 PlotGroup + +public: + static PlotGroup plotGroup() { + return PlotGroup("plot"); + } + + static PlotGroup splotGroup() { + return PlotGroup("splot"); + } + + Gnuplot &send(const PlotGroup &plot_group) { + return send(PlotGroup(plot_group)); + } + + Gnuplot &send(const PlotGroup &&plot_group) { + for(const std::string &s : plot_group.preamble_lines) { + *this << s << "\n"; + } + + std::vector spl = std::move(plot_group.plots); + + if(transport_tmpfile) { + for(size_t i=0; i tmp_files; +public: + bool debug_messages; + bool transport_tmpfile; +}; + +inline Gnuplot &operator<<(Gnuplot &gp, PlotGroup &sp) { + return gp.send(sp); +} + +inline Gnuplot &operator<<(Gnuplot &gp, PlotGroup &&sp) { + return gp.send(sp); +} + +// }}}1 + +} // namespace gnuplotio + +// The first version of this library didn't use namespaces, and now this must be here forever +// for reverse compatibility. +using gnuplotio::Gnuplot; + +#endif // GNUPLOT_IOSTREAM_H + +// {{{1 Support for 3rd party array libraries + +// {{{2 Blitz support + +// This is outside of the main header guard so that it will be compiled when people do +// something like this: +// #include "gnuplot-iostream.h" +// #include +// #include "gnuplot-iostream.h" +// Note that it has its own header guard to avoid double inclusion. + +#ifdef BZ_BLITZ_H +#ifndef GNUPLOT_BLITZ_SUPPORT_LOADED +#define GNUPLOT_BLITZ_SUPPORT_LOADED +namespace gnuplotio { + +template +struct BinfmtSender> { + static void send(std::ostream &stream) { + for(int i=0; i::send(stream); + } + } +}; + +template +struct TextSender> { + static void send(std::ostream &stream, const blitz::TinyVector &v) { + for(int i=0; i::send(stream, v[i]); + } + } +}; + +template +struct BinarySender> { + static void send(std::ostream &stream, const blitz::TinyVector &v) { + for(int i=0; i::send(stream, v[i]); + } + } +}; + +class Error_WasBlitzPartialSlice { }; + +template +class BlitzIterator { +public: + BlitzIterator() : p(nullptr) { } + BlitzIterator( + const blitz::Array *_p, + const blitz::TinyVector _idx + ) : p(_p), idx(_idx) { } + + typedef Error_WasBlitzPartialSlice value_type; + typedef BlitzIterator subiter_type; + static constexpr bool is_container = true; + + // FIXME - it would be nice to also handle one-based arrays + bool is_end() const { + return idx[ArrayDim-SliceDim] == p->shape()[ArrayDim-SliceDim]; + } + + void inc() { + ++idx[ArrayDim-SliceDim]; + } + + value_type deref() const { + static_assert((sizeof(T) == 0), "cannot deref a blitz slice"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + subiter_type deref_subiter() const { + return BlitzIterator(p, idx); + } + +private: + const blitz::Array *p; + blitz::TinyVector idx; +}; + +template +class BlitzIterator { +public: + BlitzIterator() : p(nullptr) { } + BlitzIterator( + const blitz::Array *_p, + const blitz::TinyVector _idx + ) : p(_p), idx(_idx) { } + + typedef T value_type; + typedef Error_WasNotContainer subiter_type; + static constexpr bool is_container = false; + + // FIXME - it would be nice to also handle one-based arrays + bool is_end() const { + return idx[ArrayDim-1] == p->shape()[ArrayDim-1]; + } + + void inc() { + ++idx[ArrayDim-1]; + } + + value_type deref() const { + return (*p)(idx); + } + + subiter_type deref_subiter() const { + static_assert((sizeof(T) == 0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } + +private: + const blitz::Array *p; + blitz::TinyVector idx; +}; + +template +class ArrayTraits> : public ArrayTraitsDefaults { +public: + static constexpr bool allow_auto_unwrap = false; + static constexpr size_t depth = ArrayTraits::depth + ArrayDim; + + typedef BlitzIterator range_type; + + static range_type get_range(const blitz::Array &arg) { + blitz::TinyVector start_idx; + start_idx = 0; + return range_type(&arg, start_idx); + } +}; + +} // namespace gnuplotio +#endif // GNUPLOT_BLITZ_SUPPORT_LOADED +#endif // BZ_BLITZ_H + +// }}}2 + +// {{{2 Armadillo support + +// This is outside of the main header guard so that it will be compiled when people do +// something like this: +// #include "gnuplot-iostream.h" +// #include +// #include "gnuplot-iostream.h" +// Note that it has its own header guard to avoid double inclusion. + +#ifdef ARMA_INCLUDES +#ifndef GNUPLOT_ARMADILLO_SUPPORT_LOADED +#define GNUPLOT_ARMADILLO_SUPPORT_LOADED +namespace gnuplotio { + +template static constexpr bool dont_treat_as_stl_container> = true; +template static constexpr bool dont_treat_as_stl_container> = true; +template static constexpr bool dont_treat_as_stl_container> = true; +template static constexpr bool dont_treat_as_stl_container> = true; +template static constexpr bool dont_treat_as_stl_container> = true; + +// {{{3 Cube + +template +class ArrayTraits> : public ArrayTraitsDefaults { + class SliceRange { + public: + SliceRange() : p(nullptr), col(0), slice(0) { } + explicit SliceRange(const arma::Cube *_p, size_t _row, size_t _col) : + p(_p), row(_row), col(_col), slice(0) { } + + typedef T value_type; + typedef Error_WasNotContainer subiter_type; + static constexpr bool is_container = false; + + bool is_end() const { return slice == p->n_slices; } + + void inc() { ++slice; } + + value_type deref() const { + return (*p)(row, col, slice); + } + + subiter_type deref_subiter() const { + static_assert((sizeof(T) == 0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + private: + const arma::Cube *p; + size_t row, col, slice; + }; + + class ColRange { + public: + ColRange() : p(nullptr), row(0), col(0) { } + explicit ColRange(const arma::Cube *_p, size_t _row) : + p(_p), row(_row), col(0) { } + + typedef T value_type; + typedef SliceRange subiter_type; + static constexpr bool is_container = true; + + bool is_end() const { return col == p->n_cols; } + + void inc() { ++col; } + + value_type deref() const { + static_assert((sizeof(T) == 0), "can't call deref on an armadillo cube col"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + subiter_type deref_subiter() const { + return subiter_type(p, row, col); + } + + private: + const arma::Cube *p; + size_t row, col; + }; + + class RowRange { + public: + RowRange() : p(nullptr), row(0) { } + explicit RowRange(const arma::Cube *_p) : p(_p), row(0) { } + + typedef T value_type; + typedef ColRange subiter_type; + static constexpr bool is_container = true; + + bool is_end() const { return row == p->n_rows; } + + void inc() { ++row; } + + value_type deref() const { + static_assert((sizeof(T) == 0), "can't call deref on an armadillo cube row"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + subiter_type deref_subiter() const { + return subiter_type(p, row); + } + + private: + const arma::Cube *p; + size_t row; + }; + +public: + static constexpr bool allow_auto_unwrap = false; + static constexpr size_t depth = ArrayTraits::depth + 3; + + typedef RowRange range_type; + + static range_type get_range(const arma::Cube &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(&arg); + } +}; + +// }}}3 + +// {{{3 Mat and Field + +template +class ArrayTraits_ArmaMatOrField : public ArrayTraitsDefaults { + class ColRange { + public: + ColRange() : p(nullptr), row(0), col(0) { } + explicit ColRange(const RF *_p, size_t _row) : + p(_p), row(_row), col(0) { } + + typedef T value_type; + typedef Error_WasNotContainer subiter_type; + static constexpr bool is_container = false; + + bool is_end() const { return col == p->n_cols; } + + void inc() { ++col; } + + value_type deref() const { + return (*p)(row, col); + } + + subiter_type deref_subiter() const { + static_assert((sizeof(T) == 0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + private: + const RF *p; + size_t row, col; + }; + + class RowRange { + public: + RowRange() : p(nullptr), row(0) { } + explicit RowRange(const RF *_p) : p(_p), row(0) { } + + typedef T value_type; + typedef ColRange subiter_type; + static constexpr bool is_container = true; + + bool is_end() const { return row == p->n_rows; } + + void inc() { ++row; } + + value_type deref() const { + static_assert((sizeof(T) == 0), "can't call deref on an armadillo matrix row"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + subiter_type deref_subiter() const { + return subiter_type(p, row); + } + + private: + const RF *p; + size_t row; + }; + +public: + static constexpr bool allow_auto_unwrap = false; + static constexpr size_t depth = ArrayTraits::depth + 2; + + typedef RowRange range_type; + + static range_type get_range(const RF &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(&arg); + } +}; + +template +class ArrayTraits> : public ArrayTraits_ArmaMatOrField, T> { }; + +template +class ArrayTraits> : public ArrayTraits_ArmaMatOrField, T> { }; + +// }}}3 + +// {{{3 Row + +template +class ArrayTraits> : public ArrayTraitsDefaults { +public: + static constexpr bool allow_auto_unwrap = false; + + typedef IteratorRange::const_iterator, T> range_type; + + static range_type get_range(const arma::Row &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(arg.begin(), arg.end()); + } +}; + +// }}}3 + +// {{{3 Col + +template +class ArrayTraits> : public ArrayTraitsDefaults { +public: + static constexpr bool allow_auto_unwrap = false; + + typedef IteratorRange::const_iterator, T> range_type; + + static range_type get_range(const arma::Col &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(arg.begin(), arg.end()); + } +}; + +// }}}3 + +} // namespace gnuplotio +#endif // GNUPLOT_ARMADILLO_SUPPORT_LOADED +#endif // ARMA_INCLUDES + +// }}}2 + +// {{{2 Eigen support + +// This is outside of the main header guard so that it will be compiled when people do +// something like this: +// #include "gnuplot-iostream.h" +// #include +// #include "gnuplot-iostream.h" +// Note that it has its own header guard to avoid double inclusion. + +#ifdef EIGEN_CORE_H +#ifndef GNUPLOT_EIGEN_SUPPORT_LOADED +#define GNUPLOT_EIGEN_SUPPORT_LOADED +namespace gnuplotio { + +template +static constexpr bool is_eigen_matrix = false; + +template +static constexpr bool is_eigen_matrix, T>>> = true; + +static_assert( is_eigen_matrix); +static_assert(!is_eigen_matrix); + +template +static constexpr bool dont_treat_as_stl_container>> = true; + +static_assert(dont_treat_as_stl_container); + +// {{{3 Matrix + +template +class ArrayTraits_Eigen1D : public ArrayTraitsDefaults { + class IdxRange { + public: + IdxRange() : p(nullptr), idx(0) { } + explicit IdxRange(const RF *_p) : + p(_p), idx(0) { } + + using value_type = typename RF::value_type; + typedef Error_WasNotContainer subiter_type; + static constexpr bool is_container = false; + + bool is_end() const { return idx == p->size(); } + + void inc() { ++idx; } + + value_type deref() const { + return (*p)(idx); + } + + subiter_type deref_subiter() const { + static_assert((sizeof(value_type) == 0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + private: + const RF *p; + Eigen::Index idx; + }; + +public: + static constexpr bool allow_auto_unwrap = false; + static constexpr size_t depth = ArrayTraits::depth + 1; + + typedef IdxRange range_type; + + static range_type get_range(const RF &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(&arg); + } +}; + +template +class ArrayTraits_Eigen2D : public ArrayTraitsDefaults { + class ColRange { + public: + ColRange() : p(nullptr), row(0), col(0) { } + explicit ColRange(const RF *_p, Eigen::Index _row) : + p(_p), row(_row), col(0) { } + + using value_type = typename RF::value_type; + typedef Error_WasNotContainer subiter_type; + static constexpr bool is_container = false; + + bool is_end() const { return col == p->cols(); } + + void inc() { ++col; } + + value_type deref() const { + return (*p)(row, col); + } + + subiter_type deref_subiter() const { + static_assert((sizeof(value_type) == 0), "argument was not a container"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + private: + const RF *p; + Eigen::Index row, col; + }; + + class RowRange { + public: + RowRange() : p(nullptr), row(0) { } + explicit RowRange(const RF *_p) : p(_p), row(0) { } + + using value_type = typename RF::value_type; + typedef ColRange subiter_type; + static constexpr bool is_container = true; + + bool is_end() const { return row == p->rows(); } + + void inc() { ++row; } + + value_type deref() const { + static_assert((sizeof(value_type) == 0), "can't call deref on an eigen matrix row"); + throw std::logic_error("static assert should have been triggered by this point"); + } + + subiter_type deref_subiter() const { + return subiter_type(p, row); + } + + private: + const RF *p; + Eigen::Index row; + }; + +public: + static constexpr bool allow_auto_unwrap = false; + static constexpr size_t depth = ArrayTraits::depth + 2; + + typedef RowRange range_type; + + static range_type get_range(const RF &arg) { + //std::cout << arg.n_elem << "," << arg.n_rows << "," << arg.n_cols << std::endl; + return range_type(&arg); + } +}; + +template +class ArrayTraits>> : + public std::conditional_t< + T::RowsAtCompileTime == 1 || T::ColsAtCompileTime == 1, + ArrayTraits_Eigen1D, + ArrayTraits_Eigen2D + > { }; + +// }}}3 + +} // namespace gnuplotio +#endif // GNUPLOT_EIGEN_SUPPORT_LOADED +#endif // EIGEN_CORE_H + +// }}}2 + +// }}}1 \ No newline at end of file